Swagger

This tutorials show you, how you can configure Swagger-ui with Ts.ED. Swagger use the OpenApi to describe a Rest API. Ts.ED operates the existing decorators as well as new decorators to build the a spec compliant with Swagger.

Installation

Run this command to install required dependencies by @tsed/swagger:

npm install --save @types/swagger-schema-official @tsed/swagger
1

Then add the following configuration in your ServerLoader:

import {ServerLoader, ServerSettings} from "@tsed/common";
import "@tsed/swagger"; // import swagger Ts.ED module

@ServerSettings({
  rootDir: __dirname,
  swagger: [
    {
      path: "/api-docs"
    }
  ]
})
export class Server extends ServerLoader {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

The path option for swagger will be used to expose the documentation (ex: http://localhost:8000/api-docs).

Normally, Swagger-ui is ready. You can start your server and check if it work fine.

Note: Ts.ED will print the swagger url in the console.

Swagger options

Some options is available to configure Swagger-ui, Ts.ED and the default spec information.

Key Example Description
path /api-doc The url subpath to access to the documentation.
doc hidden-doc The documentation key used by @Docs decorator to create several swagger documentations.
cssPath ${rootDir}/spec/style.css The path to the CSS file.
jsPath ${rootDir}/spec/main.js The path to the JS file.
showExplorer true Display the search field in the navbar.
spec {swagger: "2.0"} The default information spec.
specPath ${rootDir}/spec/swagger.base.json Load the base spec documentation from the specified path.
outFile ${rootDir}/spec/swagger.json Write the swagger.json spec documentation on the specified path.
hidden true Hide the documentation in the dropdown explorer list.
options Swagger-UI options SwaggerUI options. See (https://github.com/swagger-api/swagger-ui/blob/HEAD/docs/usage/configuration.md)
operationIdFormat %c.%m Format of operationId field (%c: class name, %m: method name).

Multi documentations

It also possible to create several swagger documentations with doc option:

import {ServerLoader, ServerSettings} from "@tsed/common";
import "@tsed/swagger"; // import swagger Ts.ED module

@ServerSettings({
  rootDir: __dirname,
  swagger: [
    {
      path: "/api-docs-v1",
      doc: "api-v1"
    },
    {
      path: "/api-docs-v2",
      doc: "api-v2"
    }
  ]
})
export class Server extends ServerLoader {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Then use @Docs decorators on your controllers to specify where the controllers should be displayed.

import {Controller} from "@tsed/common";
import {Docs} from "@tsed/swagger";

@Controller("/calendars")
@Docs("api-v2") // display this controllers only for api-docs-v2
export class CalendarCtrlV2 {
}

// OR
@Controller("/calendars")
@Docs("api-v2", "api-v1")  // display this controllers for api-docs-v2 and api-docs-v1
export class CalendarCtrl {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Decorators

These decorators already add a documentation on swagger:

    In addition, the Ts.ED swagger plugin given some decorators to write documentation:

      Examples

      Model documentation

      One of the feature of Ts.ED is the model definition to serialize or deserialize a JSON Object (see converters section).

      This model can used on a method controller along with @BodyParams or other decorators.

      import {Property} from "@tsed/common";
      import {Description, Example, Title} from "@tsed/swagger";
      
      export class CalendarModel {
        @Title("iD")
        @Description("Description of calendar model id")
        @Example("example1", "Description example")
        @Property()
        public id: string;
      
        @Property()
        public name: string;
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13

      Endpoint documentation

      import {Controller, Get, Post, QueryParams} from "@tsed/common";
      import {Deprecated, Description, Returns, ReturnsArray, Security, Summary} from "@tsed/swagger";
      import {CalendarModel} from "./models/Calendar";
      
      @Controller("/calendars")
      export class Calendar {
        @Get("/:id")
        @Summary("Summary of this route")
        @Description("Return a calendar from the given id")
        @Returns(404, {description: "Not found"})
        async getCalendar(@Description("A calendar Id") @QueryParams() id: string): Promise<CalendarModel> {
          return {};
        }
      
        @Get("/")
        @Description("Return a list of Calendar")
        @ReturnsArray(404, {description: "Not found"})
        getCalendars(@QueryParams() id: string): Promise<CalendarModel[]> {
          return [];
        }
      
        @Get("/v0/:id")
        @Deprecated()
        @Description("Deprecated route, use /rest/calendars/:id instead of.")
        @Returns(404, {description: "Not found"})
        getCalendarDeprecated(@QueryParams() id: string): Promise<CalendarModel> {
          return {};
        }
      
      
        @Post("/")
        @Security("calendar_auth", "write:calendar", "read:calendar")
        @Returns(CalendarModel)
        async createCalendar(): Promise<CalendarModel> {
          return {};
        }
      }
      
      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

      For endpoint which returns an array you have to use decorator instead of

      WARNING

      To update the swagger.json you have to reload the server before.

      Import Javascript

      It possible to import a Javascript in the Swagger-ui documentation. This script let you customize the swagger-ui instance.

      import {ServerLoader, ServerSettings} from "@tsed/common";
      import "@tsed/swagger"; // import swagger Ts.ED module
      
      @ServerSettings({
        rootDir: __dirname,
        swagger: [
          {
            path: "/api-docs",
            jsPath: "/spec/main.js"
          }
        ]
      })
      export class Server extends ServerLoader {
      
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15

      In your JavaScript file, you can handle Swagger-ui configuration and the instance:

      console.log(SwaggerUIBuilder.config); //Swagger-ui config
      
      document.addEventListener('swagger.init', (evt) => {
          console.log(SwaggerUIBuilder.ui); //Swagger-ui instance
      });
      
      1
      2
      3
      4
      5

      Credits

      Thanks to vologab for his contribution.