Custom endpoint decorator

Custom endpoint decorator could be interesting when you want to handle request and perform actions before or after the endpoint method. It's based on the middleware but this offer you more options and controller over your decorated endpoint.

One of the usecase already implemented by Ts.ED is the :

import {NotAcceptable} from "ts-httpexceptions";
import {EndpointInfo, Middleware, Req} from "../decorators";
import {IMiddleware} from "../interfaces";

/**
 * @middleware
 */
@Middleware()
export class AcceptMimesMiddleware implements IMiddleware {
  public use(@EndpointInfo() endpoint: EndpointInfo, @Req() request: Req): void {
    const mimes = endpoint.get(AcceptMimesMiddleware) || [];

    const find = mimes.find((mime: string) => request.accepts(mime));

    if (!find) {
      throw new NotAcceptable(mimes.join(", "));
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

You can see in this example the usage of endpoint.get from . This method contain all options which can be passed to decorator associated to AcceptMimesMiddleware.

import {Controller, Get} from "@tsed/common";
import {AcceptMime} from "@tsed/common/src/mvc/decorators/method/acceptMime";

@Controller("/mypath")
export class MyCtrl {
  @Get("/")
  @AcceptMime("application/json")
  public getResource() {
  }
}
1
2
3
4
5
6
7
8
9
10

TIP

This example use decorator with one option, the application/json. This option will be set to endpoint.get seen before with AcceptMimesMiddleware example and can be retrieved by using endpoint.get(AcceptMimesMiddleware).

Ts.ED provide API to create you own decorator like which register the options and at least one middleware with theses decorators and utils:

  • , , , or for middleware registration,
  • if you want to combine different decorators,
  • or to register options.

For example, we can take the decorator as example and see how it works. Here his code:

import {AcceptMimesMiddleware, UseBefore} from "@tsed/common";
import {applyDecorators, StoreSet} from "@tsed/core";

export function AcceptMime(...mimes: string[]): Function {
  return applyDecorators(
    StoreSet(AcceptMimesMiddleware, mimes),
    UseBefore(AcceptMimesMiddleware)
  );
}
1
2
3
4
5
6
7
8
9

TIP

It also possible to create a custom endpoint decorator without Ts.ED middleware. If your action is really small, you can register a pur express middleware to reach better performance.

import {applyDecorators, StoreSet} from "@tsed/core";
import {IResponseOptions, UseAfter, mapReturnedResponse} from "@tsed/common";

export function Status(code: number, options: IResponseOptions = {}) {
  const response = mapReturnedResponse(options);

  return applyDecorators(
    StoreSet("statusCode", code),
    StoreSet("response", response),
    StoreSet("responses", {[code]: response}),
    UseAfter((request: any, response: any, next: any) => {
      if (response.statusCode === 200) {
        response.status(code);
      }
      next();
    })
  );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Built-in endpoint decorators

Many other decorators are implemented and can be take as example to build your own endpoint decorator. Just follow the links here and click on source link to see source code on Github: