# Platform API

Ts.ED use now, the Platform API to create an application. Platform API give an abstraction layer between your code written with Ts.ED and the Express.js code. It means, a large part of your code isn't coupled with Express itself and can be used with another Platform like Koa.js in future (Ts.ED v6).

There are some changes between ServerLoader API (v4/v5) and Platform API (v5.56.0+/v6), to get the original Express Application, Request or Response. This page will describe how you can get these instance with the new API.

# Platform classes

    # Create application

    The way to create Ts.ED application, add middlewares, configure Express.Application are impacted by the new Platform API.

    If you use , you'll probably know this example to create a Ts.ED application:

    import {ServerLoader, ServerSettings} from "@tsed/common";
    import {MyMiddleware} from "./MyMiddleware";
    import * as bodyParser from "body-parser";
    import * as compress from "compression";
    import * as cookieParser from "cookie-parser";
    import * as methodOverride from "method-override";
    
    export const rootDir = __dirname;
    
    @ServerSettings({
      rootDir,
      viewsDir: `${rootDir}/views`
    })
    export class Server extends ServerLoader {
      $beforeRoutesInit() {
        this
         .use(MyMiddleware)
         .use(cookieParser())
         .use(compress({}))
         .use(methodOverride())
         .use(bodyParser.json())
         .use(bodyParser.urlencoded({
           extended: true
         }));
       
        // configure express app
        this.set("views", this.settings.get('viewsDir'));
        this.engine("ejs", ejs);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    With Platform API you have to inject to register a middleware and set configuration to Express.Application:

    import {Configuration, PlatformApplication} from "@tsed/common"; 
    import {Inject, Constant} from "@tsed/di";
    import {MyMiddleware} from "./MyMiddleware";
    import * as bodyParser from "body-parser";
    import * as compress from "compression";
    import * as cookieParser from "cookie-parser";
    import * as methodOverride from "method-override";
    
    export const rootDir = __dirname;
    
    @Configuration({
      rootDir,
      viewsDir: `${rootDir}/views`
    })
    export class Server {
      @Constant("viewsDir")
      viewsDir: string;
    
      @Inject()
      app: PlatformApplication<Express.Application>;
    
      $beforeRoutesInit() {
        this.app
         .use(MyMiddleware)
         .use(cookieParser())
         .use(compress({}))
         .use(methodOverride())
         .use(bodyParser.json())
         .use(bodyParser.urlencoded({
           extended: true
         }));
      
        // configure express app
        this.app.raw.set("views", this.viewsDir);
        this.app.raw.engine("ejs", ejs);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    TIP

    With Platform API, the Server class is considered as a . It means, you can use decorator like and to get any configuration, provider or service from the DI registry.

    # Inject service in the Server

    With , inject a provider can be done as follows:

    import {ServerLoader, ServerSettings} from "@tsed/common";
    import {MyService} from "./services/MyService";
    
    @ServerLoader({
    })
    export class Server extends ServerLoader {
      $beforeRoutesInit() {
        const myService = this.injector.get<MyService>(MyService);
    
        myService.getSomething();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    Now Platform API, the Server class is considered as a . It means, you can use decorator like and to get any configuration, provider or service from the DI registry.

    import {Configuration} from "@tsed/common"; 
    import {Inject} from "@tsed/di";
    import {MyService} from "./services/MyService";
    
    @Configuration({})
    export class Server {
      @Inject()
      myService: MyService;
    
      $beforeRoutesInit() {
        this.myService.getSomething();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    # Get Application

    Express application is the instance initiated on Ts.ED server bootstrapping. Originally, Ts.ED expose an symbol to inject the Express.Application.

    import {Injectable} from "@tsed/di";
    import {ExpressApplication} from "@tsed/common";
    
    @Injectable()
    class MyService {
      constructor(@ExpressApplication private app: ExpressApplication) {
      }
     
      getExpressApp(){
         return this.app;
      }
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    With Platform API you have to inject and use the raw attribute to get the Express.Application:

    import {Injectable, Inject} from "@tsed/di";
    import {PlatformApplication} from "@tsed/common";
    import {MyMiddleware} from "../middlewares/MyMiddleware";
    
    @Injectable()
    class MyService {
      @Inject()
      app: PlatformApplication<Express.Application>;
     
      getExpressApp(){
         return this.app.raw;
      }
      
      $onInit() {
        // With Platform API is also possible to add middleware with a service, module, etc...
        this.app.use(MyMiddleware); 
      }
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    # Request and Response

    There no big change over Response and Request, you can always get and by using decorators. With the Platform API, your able also to use decorator to deal with the or high level API.

    See Request context page to get more details.

    # Statics files

    Since v5.65.0 Platform API manage also the statics files. The is now deprecated in favor of PlatformApplication.statics() method.

    Before:

    import {Injectable} from "@tsed/di";
    import {ServeStaticService} from "@tsed/common";
    
    @Injectable()
    class MyService {
      constructor(private service: ServeStaticService) {
      }
     
      $onReady () {
        this.service.statics({"/endpoint":  __dirname + "/publics"});
      }
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    After:

    import {Injectable} from "@tsed/di";
    import {PlatformApplication} from "@tsed/common"; 
    
    @Injectable()
    class MyService {
      constructor(private app: PlatformApplication) {
      }
     
      $onReady () {
        this.app.statics("/endpoint",   {root: __dirname + "/publics"});
      }
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # Catch exceptions

    The new Platform API introduce a new way to catch an exception with the decorator and to let you control the exact flow of control and the content of the response sent back to the client.

    See Exception filter page to get more details.