# 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.