Fulminate Class-Based View Router
This package introduces class-based views (controllers) for Express.js. Designed to be used with TypeScript. Heavily inspired by Django's class based views. This is a full revision of previously published Fulminate Router. To install current version:
npm i --save @fulminate/router
To use the deprecated version, install it with:
npm i @fulminate/router@1.1.6
Migration guide (1.x.x to 2.x.x)
No migration. Its a 100% redone package.
Example of use:
You first need to wire up the server. Fulminate class-based views wrap up Express server. If you've already started working with Express, you can simply inject your code into Fulminate CBV without rewriting.
Creating brand-new express server with Fulminate Router
import * as morgan from 'morgan';
import { FulminateRouter } from '@fulminate/router';
const fS = new FulminateRouter();
// Provide paths and names of your Fulminate CBV files to make the router automatically require them.
// NOTE: You can provide strings, arrays of strings, regexes and arrays of regexes.
fS.registerViews(__dirname, [ /\/*.controller.js$/ ]);
fS.wireUp();
const server = fS.getServer();
// Add any required dependencies
// NOTE: Body and cookie parsers are already injected into Fulminate Router.
server.use(morgan('dev'));
// Set up view engine
server.set('view engine', 'ejs')
.set('views', './')
.engine('.html', require('ejs').renderFile)
;
server.listen(3000);
Injecting existing Express server into Fulminate Router
import * as express from 'express';
import * as morgan from 'morgan';
import { FulminateRouter } from '@fulminate/router';
const server = express();
server.use(morgan('dev'));
// Set up view engine
server.set('view engine', 'ejs')
.set('views', './')
.engine('.html', require('ejs').renderFile)
;
const fS = new FulminateRouter(server);
fS.registerViews(__dirname, [ /\/*.controller.js$/ ]);
fS.wireUp();
const server = fS.getServer();
// NOTE: You need to listen to the server taken from Fulminate Router.
fS.getServer().listen(3000);
Examples of view classes
import { Body, ClassBasedView, GetCookies, GetHeaders, QueryParams, RequestParams, SetCookie, SetHeader } from '@fulminate/class-based-view';
// View marked 'asJson: true' will return JSON.
@ClassBasedView({
route: '/',
asJson: true,
})
// Set response headers
@SetHeader({ key: 'X-Powered-By', value: 'Someone_Else' })
@SetHeader({ key: 'Authorization', value: 'ThisIsToken' })
export class TestView {
// Decorated variables will not be listed in the response object and are meant to be used internally.
@GetCookies()
private _cookies: object;
// To visually simplify the code, use 'private' for non-enumerable values and 'public' for enumerable ones.
public title = 'TestView works!';
// To make decorated variables enumerable, simply use a getter.
// NOTE: You need to target at least 'es5' in tsconfig to be able to use getters.
public get cookies(): object {
return this._cookies;
}
}
// Provide the route, marking request parameters with colons (':').
// NOTE: Template logic only works if you set up view engine.
@ClassBasedView({
route: '/:param',
template: 'index.html',
})
export class Test2View {
// Set cookies (name of the variable is used as a cookie name and its value is used as cookie value).
@SetCookie() cookieTheAnswer = '42';
@SetCookie() whatsHerName = 'noname';
public title: string;
// Get access to request headers
@GetHeaders()
private headers: object;
// Get query params
// NOTE: Providing 'required' option to decorators will cause an error if the required data does not exist on request object.
@QueryParams({ required: true })
private queryParams: object;
// Explicitly define which cookie or cookies are required
@GetCookies({ required: true, explicitly: [ 'cookieTheAnswer' ]})
private cookies: object;
// Get request params
// NOTE: Request params must also be present in the route option of @ClassBasedView decorator.
@RequestParams()
private requestParams: object;
// Adjust values in the constructor.
public constructor() {
this.title = 'Test2View works!'
}
}
// Define HTTP methods other than GET.
// NOTE: case-insensitive.
@ClassBasedView({
route: '/',
method: 'POST',
asJson: true,
})
export class TestPostView {
public name: string = "TestPostView works!";
// Get the body of the request
@Body()
private body;
}