ServerLoader
Lifecycle Hooks
ServerLoader calls a certain number of methods (hooks) during its initialization phase (lifecycle). This lifecycle hooks that provide visibility into these key life moments and the ability to act when they occur.
This schemes resume the order of the server's lifecycle and a service's lifecycle.
Hook method | Description |
---|---|
constructor | On this phase nothing is constructed. Express app isn't created. |
$onInit | Respond when the server starting his lifecycle. Is good place to initialize Database connection. |
$onMountingMiddlewares | This hooks is the right place to configure the middlewares that must be used with your ExpressApplication. At this step, InjectorService and services are ready and can be injected. The Controllers isn't built. |
$afterRoutesInit | Respond just after all Controllers are built. You can configure the serve-static middleware on this phase. |
$onReady | Respond when the server is ready. At this step, HttpServer or/and HttpsServer object is available. The server listen the port. |
$onServerInitError | Respond when an error is triggered on server initialization. |
For more information on Service hooks see Services lifecycle hooks
Hooks examples
ServerLoader.$onInit(): void | Promise
During this phase you can initialize your database connection for example. This hook accept a promise as return and let you to wait the database connection before run the next lifecycle's phase.
Example with mongoose Api:
class Server extends ServerLoader {
async $onInit(): Promise {
return new Promise((resolve, reject) => {
const db = Mongoose.connect(credentials);
db.once('open', resolve);
db.on('error', reject); // if error occurs, it will be intercepted by $onServerInitError
});
}
}
2
3
4
5
6
7
8
9
10
11
ServerLoader.$onMountingMiddlewares(): void | Promise
Some middlewares are required to work with all decorators as follow:
cookie-parser
are required to use@CookieParams
,body-parser
are require to use@BodyParams
,method-override
.
At this step, services are built.
Example of middlewares configuration:
class Server extends ServerLoader {
async $onMountingMiddlewares(): void | Promise {
const cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
compress = require('compression'),
methodOverride = require('method-override'),
session = require('express-session');
this.use(GlobalAcceptMimesMiddleware)
.use(bodyParser.json())
.use(bodyParser.urlencoded({
extended: true
}))
.use(cookieParser())
.use(compress({}))
.use(methodOverride());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$onMountingMiddlewares
accept a promise to defer the next lifecycle's phase.
ServerLoader.$afterRoutesInit(): void | Promise
This hook will be called after all the routes are collected by ServerLoader.mount()
or ServerLoader.scan()
.
When all routes are collected, ServerLoader build the controllers then ServerLoader mount each route to the ExpressApp.
This hook is the right place to add middlewares before the Global Handlers Error.
class Server extends ServerLoader {
public $afterRoutesInit(){
}
}
2
3
4
5
ServerLoader.$onReady(): void
On this phase your Express application is ready. All controllers are imported and all services is constructed. You can initialize other server like a Socket server.
Example:
class Server extends ServerLoader {
public $onReady(): void {
console.log('Server ready');
const io = SocketIO(this.httpServer);
// ...
}
}
2
3
4
5
6
7
8
If you want integrate Socket.io, you can see the tutorials "How to integrate Socket.io".
Versioning REST API
Ts.ED provide the possibility to mount multiple Rest path instead of the default path /rest
.
You have two methods to configure all global endpoints for each directories scanned by the ServerLoader.
With decorator (Recommended)
import {ServerLoader, ServerSettings} from "@tsed/common";
import Path = require("path");
const rootDir = Path.resolve(__dirname);
@ServerSettings({
rootDir,
mount: {
"/rest": "${rootDir}/controllers/current/**/*.js",
"/rest/v1": [
"${rootDir}/controllers/v1/users/*.js",
"${rootDir}/controllers/v1/groups/*.js"
]
}
})
export class Server extends ServerLoader {
}
new Server().start();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Note: mount attribute accept a list of glob for each endpoint. That lets you declare a resource versioning.
With ServerLoader API
import {ServerLoader, IServerLifecycle} from "@tsed/common";
import Path = require("path");
export class Server extends ServerLoader implements IServerLifecycle {
constructor() {
super();
const appPath: string = Path.resolve(__dirname);
this.mount('rest/', appPath + "/controllers/**/**.js")
.mount('rest/v1/', [
appPath + "/controllers/v1/users/**.js",
appPath + "/controllers/v1/groups/**.js"
])
.createHttpServer(8000)
.createHttpsServer({
port: 8080
});
}
}
new Server().start();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
← Interceptors Testing →