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
Decorator | Usage |
---|---|
@ApiDocGroup | mark controller |
@ApiDoc | mark controller method |
@PropDoc | mark 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'
}
}