Skip to main content

Swagger Docs

Features

  • Only THREE simple decorators
  • Infer ALL types and generate examples
  • Full support of OpenAPI 3.0.x
  • Password protection
  • Working with Summer core validation decorator (@Max @Email optional(?)...)
  • Can read TypeORM comment
  • Reuse Summer ResponseError

Install Swagger Plugin

npm install @summer-js/swagger

Config Swagger

in config/default.config.ts or other [env].config.ts

import { SwaggerConfig } from '@summer-js/swagger';

export const SWAGGER_CONFIG: SwaggerConfig = {
docPath: '/swagger',
password: 'abc123',
info: { title: 'Summer', version:"0.0.1" }
}

Swagger Decorators

DecoratorUsage
@ApiDocGroupmark controller
@ApiDocmark controller method
@PropDocmark DTO property

Most Simple Usage

A single line of code can generate a full swagger document
import { Body, Controller, Get, Query, PathParam, Post } from '@summer-js/summer'
import { ApiDoc, ApiDocGroup } from '@summer-js/swagger'

class AddMovieRequest {
name: string
year: string
}

class Movie {
id: number
name: string
year: string
}

@Controller
@ApiDocGroup('Movie APIs')
export class MovieController {
@Get('/movies')
list(@Query search: string) {
const movies: Movie[] = [
{ id: 1, name: 'Titanic', year: '1997' },
{ id: 2, name: 'CODA', year: '2021' }
]
return movies
}

@Get('/movies/:id')
detail(@PathParam id: string) {
const movies: Movie = { id: 1, name: 'Titanic', year: '1997' }
return movies
}

@Post('/movies')
add(@Body body: AddMovieRequest) {
const movies: Movie = { id: 1, name: 'Titanic', year: '1997' }
return movies
}
}

Full Usage

import { Body, Controller, Get, Query, PathParam, Header, Post } from '@summer-js/summer'
import { ApiDoc, ApiDocGroup, PropDoc } from '@summer-js/swagger'

class AddMovieRequest {
@PropDoc("Movie Name", "Titanic")
name: string

@PropDoc("Movie Release Year", 1997)
year: string
}

class Movie {
id: number
name: string
year: string
}

@Controller
@ApiDocGroup('Movie API', { category: 'Client API' })
export class MovieController {
@ApiDoc('Fetch movie list', {
description: 'This api return a full list of movies',
})
@Get('/movies')
list(@Query search: string) {
const movies: Movie[] = [
{ id: 1, name: 'Titanic', year: '1997' },
{ id: 2, name: 'CODA', year: '2021' }
]
return movies
}

@ApiDoc('Get a specific movie detail by id', {
errors: [
{
statusCode: 404,
description: 'Not Found',
example: '404 Not Found',
}
]
})
@Get('/movies/:id')
detail(@PathParam id: string) {
const movie: Movie = { id: 1, name: 'Titanic', year: '1997' }
return movie
}

@ApiDoc('Add a new movie', {
description: ''
})
@Post('/movies')
add(@Body body: AddMovieRequest) {
const movies: Movie = { id: 1, name: 'Titanic', year: '1997' }
return movies
}
}
Return type and Example

Summer can infer class return type and generate examples automatically, return type must be a Class.

Categorize APIs to different pages

config category in @ApiDocGroup('',{category:'App APIs'})

Ordering APIs

config order in @ApiDocGroup('',{order:1})

Add Access Password

export const SWAGGER_CONFIG: SwaggerConfig = {
docPath: '/swagger',
password: 'xxxxxxxxxx',
.....
}

Reuse ResponseError

ResponseError instance can be set to errors example

// define error
const MovieNotFoundError = new ResponseError(404,"Movie not found")

@ApiDoc('Get a specific movie detail by id', {
errors: [ MovieNotFoundError ]
})
@Get('/movies/:id')
detail(@PathParam id: string) {
const movie: Movie = { id: 1, name: 'Titanic', year: '1997' }
if(!movie){
throw MovieNotFoundError
}
return movie
}

Read TypeORM comment

TypeORM entity comment can be read to swagger DTO property description. To enable this feature, set readTypeORMComment to true in SWAGGER_CONFIG

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

@Entity()
export class Todo {
@PrimaryGeneratedColumn()
id: number

@Column({ comment: 'To do content' })
content: string

@Column({ comment: 'Is already done' })
isDone: boolean
}
export const SWAGGER_CONFIG: SwaggerConfig = {
docPath: '/swagger',
readTypeORMComment: true,
info: {
title: 'Summer',
description: 'Last build at: ' + new Date(SUMMER_BUILD_TIMESTAMP),
version: '1.0.0'
}
}

Add API Auth

export const SWAGGER_CONFIG: SwaggerConfig = {
docPath: '/swagger',
info: { title: 'Summer', version: '1.0.0' },
securitySchemes: {
Auth: {
type: 'apiKey',
in: 'header',
name: 'Authorization'
}
}
}
@Get('/movies/:id',{ security: [{ Auth: [] }] })
detail(@PathParam id: string) {
const movie: Movie = { id: 1, name: 'Titanic', year: '1997' }
return movie
}

Show Build Time

export const SWAGGER_CONFIG: SwaggerConfig = {
docPath: '/swagger',
info: {
title: 'Summer',
description: 'Last build at: ' + new Date(SUMMER_BUILD_TIMESTAMP),
version: '1.0.0'
}
}