An egg-swagger plugin (support Typescript) for serving a Swagger UI, params should follow JSON Schema specification (recommend use Ajv),using Swagger (OpenAPI v2) schemas automatically generated from your controller JSDoc comments.
CAUTION: Require Node.js 10.x or higher!
$ npm i swagger-egg --save
Enable this plugin, visting index.html
under static resource directory
and you will get the Swagger UI page. Visiting http://localhost:7001/public/index.html
to get the default Swagger-UI
page.
Project Example:
// {app_root}/config/plugin.js
exports.swaggerEgg = {
enable: true,
package: "swagger-egg",
};
swagger.info
is optional and will be generated from your application'spackage.json
if not exist.swagger.tags
is required if controller's JSDoc comments usedtags
.
// {app_root}/config/config.default.js
exports.swaggerEgg = {
schema: {
path: '/app/schema', // JSON Schema directory
},
swagger: {
info: {
title: 'Test swagger',
description: 'Testing the Fastify swagger API',
version: '0.1.0'
},
externalDocs: {
url: 'https://swagger.io',
description: 'Find more info here'
},
host: '127.0.0.1:7001', // should be egg server's host, otherwise result in cross origin error
schemes: ['http', 'https'],
consumes: ['application/json'],
produces: ['application/json'],
tags: [
{ name: 'user', description: 'User related end-points' }
],
securityDefinitions: {
api_key: {
type: 'apiKey', // basic/apiKey/oauth2
name: 'Authorization', // selfdefined parameter, usually use 'Authorization'
in: 'header', // query or header, usually use 'header'
},
github_auth: {
type: 'oauth2',
authorizationUrl: 'http://swagger.io/api/oauth/dialog',
flow: 'implicit',
scopes: {
'write:homes': 'modify home info',
'read:homes': 'read home info',
},
},
},
security: [
{
api_key: [], // select 'api_key' to security(defined in `securityDefinitions`)
},
], // Cacution: security is array type
typescriptJsonSchema: false, // use typescript json schema. (see: https://github.com/YousefED/typescript-json-schema)
}
};
see config/config.default.js for more detail.
#swagger-api
in front of JSDoc comments is required!
/**
* #swagger-api
*
* @function index
*/
async index() {
this.ctx.body = 'hi, #swagger-api example'
}
The JSDoc @function
is required, which is used to search router info from app/router.js
.
/**
* Function example #swagger-api
*
* @function index
*/
async index() {
this.ctx.body = 'hi, function example'
}
The JSDoc @summary
is used to describe the function's summary.
/**
* Function example #swagger-api
*
* @function index
* @summary This is function's summary.
*/
async index() {
this.ctx.body = 'hi, summary example'
}
#tags
is used for logical grouping of operations by resources or any other qualifier.
NOTE: Multiple tags should be separated by whitespace.
/**
* Tags example #swagger-api
*
* @function index
* @description #tags user admin
*/
async index() {
this.ctx.body = 'hi, tags example'
}
#produces
is used for declaring API response mimetype.
NOTE: Multiple mimetypes should be separated by whitespace.
/**
* Produces example #swagger-api
*
* @function index
* @description #produces application/json
*/
async index() {
this.ctx.body = 'hi, produces example'
}
#consumes
is used for declaring API request mimetype.
NOTE: Multiple mimetypes should be separated by whitespace.
/**
* Consumes example #swagger-api
*
* @function index
* @description #consumes application/json
*/
async index() {
this.ctx.body = 'hi, consumes example'
}
#parameters
is used for declaring api request parameters.
NOTE: Description is separated by -
and others are separated by whitespace.
NOTE:
In
should be within'query', 'header', 'path', 'formData', 'body'
according to Swagger specification.Required
should beboolean type
.Type
should be within'string', 'number', 'integer', 'boolean', 'array', 'file'
.
/**
* Parameters example #swagger-api
*
* @function index
* @description #parameters id path schema.id true - id parameter
*/
async index() {
this.ctx.body = 'hi, parameters example'
}
#responses
is used for declaring api response info.
NOTE: Description is separated by -
and others are separated by whitespace.
/**
* Responses example #swagger-api
*
* @function index
* @description #responses schema.user - user responses
*/
async index() {
this.ctx.body = 'hi, responses example'
}
Schema should follow the JSON Schema specification. You can use Ajv to validate it.
Change swaggerEgg.schema.path
field in config file if you want to redefine it.
// {app_root}/app/schema/users.js
module.exports = {
type: 'object',
properties: {
id: {
type: 'string',
description: 'user id'
},
name: {
type: 'string',
description: 'user name'
},
age: {
type: 'number',
description: 'user age'
},
},
required: [ 'id', 'name', 'age' ],
additionalProperties: false,
};
// {app_root}/app/controller/users.js
const Controller = require('egg').Controller;
class UserController extends Controller {
/**
* Index action #swagger-api
*
* @function index
* @memberof UserController
* @description #tags user
* @description #produces application/json
* @description #parameters index query schema.definitions.index true - parameter index
* @description #responses 200 schema.user - index response
*/
async index() {
this.ctx.body = 'hi, index action' + this.app.plugins.swaggerEgg.name;
}
/**
* New action #swagger-api
*
* @function new
* @memberof UserController
* @description #tags user
* @description #consumes application/x-www-form-urlencoded
* @description #produces application/json
* @description #parameters userInfo body schema.user true - parameter userInfo
* @description #responses 200 schema.user - new response
*/
async new() {
this.ctx.body = 'hi, new action' + this.app.plugins.swaggerEgg.name;
}
/**
* Show action #swagger-api
*
* @function show
* @memberof UserController
* @description #tags user
* @description #produces application/json
* @description #parameters id path schema.definitions.id true - parameter id
* @description #responses 200 schema.user - show response
*/
async show() {
this.ctx.body = 'hi, show action' + this.app.plugins.swaggerEgg.name;
}
/**
* Edit action #swagger-api
*
* @function edit
* @memberof UserController
* @description #tags user
* @description #consumes application/x-www-form-urlencoded
* @description #produces application/json
* @description #parameters id path schema.definitions.id true - parameter id
* @description #parameters userInfo body schema.user true - parameter userInfo
* @description #responses 200 schema.user - edit response
*/
async edit() {
this.ctx.body = 'hi, edit action ' + this.app.plugins.swaggerEgg.name;
}
/**
* Create action #swagger-api
*
* @function create
* @memberof UserController
* @description #tags user
* @description #consumes application/x-www-form-urlencoded
* @description #produces application/json
* @description #parameters userInfo body schema.user true - parameter userInfo
* @description #responses 200 schema.user - create response
*/
async create() {
this.ctx.body = 'hi, create action ' + this.app.plugins.swaggerEgg.name;
}
/**
* Update action #swagger-api
*
* @function update
* @memberof UserController
* @description #tags user
* @description #consumes application/x-www-form-urlencoded
* @description #produces application/json
* @description #parameters id path schema.definitions.id true - parameter id
* @description #parameters userInfo body schema.user true - parameter userInfo
* @description #responses 200 schema.user - update response
*/
async update() {
this.ctx.body = 'hi, update action ' + this.app.plugins.swaggerEgg.name;
}
/**
* Destory action #swagger-api
*
* @function destory
* @memberof UserController
* @description #tags user
* @description #consumes application/json
* @description #produces application/json
* @description #parameters id path schema.definitions.id false - parameter id
* @description #responses 200 schema.user - destory response
*/
async destory() {
this.ctx.body = 'hi, destory action ' + this.app.plugins.swaggerEgg.name;
}
}
module.exports = UserController;
Please open an issue here.