使用swagger配置接口文档
添加swaggerloader
import basicAuth from 'express-basic-auth';
import { MicroframeworkLoader, MicroframeworkSettings } from 'microframework-w3tec';
import * as path from 'path';
import * as swaggerUi from 'swagger-ui-express';
import * as express from 'express';
import { env } from '../env';
export const swaggerLoader: MicroframeworkLoader = (settings: MicroframeworkSettings | undefined) => {
if (settings && env.swagger.enabled) {
const expressApp = settings.getData('express_app');
// 获取swagger配置 文件
const swaggerFile = require(path.join(__dirname, '..', env.swagger.file));
// 获取swagger基本信息
swaggerFile.info = {
title: env.app.name,
description: env.app.description,
version: env.app.version,
};
// 配置swagger服务请求路径
swaggerFile.servers = [
{
url: `${env.app.schema}://${env.app.host}:${env.app.port}${env.app.routePrefix}`,
},
];
// 创建swagger服务。
expressApp.use(
env.swagger.route, // 配置swagger路由
env.swagger.username ? basicAuth({
users: {
[`${env.swagger.username}`]: env.swagger.password,
},
challenge: true,
}) : (req:express.Request, res:express.Response, next:express.NextFunction) => next(),
swaggerUi.serve,
swaggerUi.setup(swaggerFile)
);
}
};
swaggerloader需要配置在expressloader实例之后。因为swagger需要拿到express的实例进行使用。所以在这之前我们也需要把express里把实例存到全局的setting中。
···········
const debug = iDebug('node-mvc:server');
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
settings?.setData('express_app',app);
const server = http.createServer(app);
server.listen(port);
// server.on('error', onError);
server.on('listening', onListening);
···········
这里一个比较值得注意的地方就是使用的use里有一个basicAuth方法,这里是调用了express-basic-auth,限制了swagger页面的访问权限。毕竟这种接口文档也不能给所有人看到的嘛。而use的第一个参数是路径。其他后面可以接多个function。只有前面的一个function使用了next才会进入下一个function。这大概是这部分原理的实现。
swagger.json
接着来看看swagger.json的配置。
{
"swagger": "2.0", // swagger文版本
"info": {
"description": "node-mvc", // 描述
"version": "1.0.0", // 版本号
"title": "node-mvc", // 标题
"contact": {
"email": "xxxxxxxxxxxm@163.com" // 联系邮箱
}
},
"host": "localhost:3000", // 配置服务路径
"basePath": "/api", // 根路径
"tags": [ // 标签
{
"name": "User",
"description": "关于用户类的操作"
}
],
"schemes": [ // 请求协议
"http"
],
"paths": { // 路径
"/user": {
"post": { // restful methods
"tags": [
"User" // 对应的标签
],
"summary": "新建用户", // 概括
"description": "添加一个用户", // 描述
"operationId": "createUser", // 操作id,会对应hash值
"produces": [
"application/json" // 返回格式
],
"parameters": [ // 参数
{
"in": "body",
"name": "body",
"description": "创建一个用户对象",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": { // 返回内容
"default": {
"description": "successful operation"
}
}
},
"get": {
"tags": [
"User"
],
"summary": "获取用户列表",
"description": "获取用户列表",
"operationId": "getUserList",
"produces": [
"application/json"
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/{id}": {
"delete": {
"tags": [
"User"
],
"summary": "删除单个用户",
"description": "根据用户id删除用户",
"operationId": "removeUserById",
"parameters": [
{
"name": "id",
"in": "path",
"description": "用户id",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "ok",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"code": {
"type": "number"
},
"message": {
"type": "string"
},
"data": {
"$ref": "#/definitions/User"
}
}
}
}
}
}
}
},
"put": {
"tags": [
"User"
],
"summary": "修改单个用户",
"description": "根据用户id修改用户",
"operationId": "updateUserById",
"parameters": [
{
"name": "id",
"in": "path",
"description": "用户id",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"in": "body",
"name": "body",
"description": "创建一个用户对象",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"200": {
"description": "ok",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"code": {
"type": "number"
},
"message": {
"type": "string"
},
"data": {
"$ref": "#/definitions/User"
}
}
}
}
}
}
}
},
"get": {
"tags": [
"User"
],
"summary": "获取单个用户",
"description": "根据用户id获取用户",
"operationId": "getUserById",
"parameters": [
{
"name": "id",
"in": "path",
"description": "用户id",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "ok",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"code": {
"type": "number"
},
"message": {
"type": "string"
},
"data": {
"$ref": "#/definitions/User"
}
}
}
}
}
}
}
}
}
},
"securityDefinitions": { // 安全校验配置
"api_key": {
"type": "apiKey",
"name": "authorization",
"in": "header"
}
},
"definitions": { // 定义model
"User": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "用户id"
},
"wx_name": {
"type": "string",
"description": "微信名"
},
"avatar": {
"type": "string",
"description": "头像地址"
},
"name": {
"type": "string",
"description": "自定义名称"
},
"role": {
"type": "string",
"description": "角色"
},
"init": {
"type": "string",
"description": "是否初始化"
}
}
}
},
"externalDocs": {
"description": "Find out more about Swagger",
"url": "http://swagger.io"
}
}
注意。这里的swagger要规定好2.0版本。不同版本有不同版本的配置方法。也可以配置为openapi": "3.0.0"
petstore.swagger.io/v2/swagger.…这里附一份官网的详细配置
修改controller配置
import { Get, JsonController, Post, Body, OnUndefined, Param, Delete, Put } from "routing-controllers";
import { UserService } from '../services/UserService';
import { User } from "../models/User";
import AjaxResponse from "../commonClass/AjaxResponse";
@JsonController('/user')
export default class UserController {
constructor(
private userService: UserService
) {
}
@Get()
public find(): Promise<AjaxResponse> {
return this.userService.find();
}
@Post()
public create(@Body() user: User): Promise<AjaxResponse> {
return this.userService.create(user);
}
@Put('/:id')
public update(@Body() user: User,@Param('id') id: string): Promise<AjaxResponse> {
return this.userService.update(id,user);
}
@Get('/:id')
public one(@Param('id') id: string): Promise<AjaxResponse> {
return this.userService.findOne(id);
}
@Delete('/:id')
public delete(@Param('id') id: string): Promise<AjaxResponse> {
return this.userService.delete(id);
}
}
这里我们添加了一个AjaxResponse作为统一的返回对象。
export default class AjaxResponse{
public status:number; // 0-成功 1-失败
public message:string|undefined; // 返回的内容
public data:string;
constructor(status:number,message?:string,data?:any)
{
this.status = status;
this.message = message;
this.data = data;
}
}
同样的。既然修改了返回参数。那么service类就也要随之更改
import { Service } from 'typedi';
import { OrmRepository } from 'typeorm-typedi-extensions';
import uuid from 'uuid';
import { User } from '../models/User';
import { UserRepository } from '../repositories/UserRepository';
import AjaxResponse from '../common_class/AjaxResponse';
@Service()
export class UserService {
constructor(
@OrmRepository() private userRepository: UserRepository,
) { }
public async find(): Promise<AjaxResponse> {
const list = await this.userRepository.find();
return new AjaxResponse(1,'获取成功',list);
}
public async findOne(id: string): Promise<AjaxResponse> {
const user = await this.userRepository.findOne({ id });
return new AjaxResponse(1,'获取成功',user);
}
public async create(user: User): Promise<AjaxResponse> {
user.id = uuid.v1();
const newUser = await this.userRepository.save(user);
return new AjaxResponse(1,'新增成功',user);
}
public async update(id: string, user: User): Promise<AjaxResponse> {
user.id = id;
const updateUser = await this.userRepository.save(user);
return new AjaxResponse(1,'修改成功',updateUser);
}
public async delete(id: string): Promise<AjaxResponse> {
const result = await this.userRepository.delete(id);
return new AjaxResponse(1,'删除成功');
}
}
修改启动命令
这些模块都搭建好之后要记得把启动命令修改一下,因为之前都只是监听ts文件的改变,并没有监听json文件。所以要加上json文件的配置。
"dev": "export NODE_ENV=development&&nodemon --watch 'src/' -e ts,json --exec 'ts-node' ./src/app.ts"
主要也就是使用逗号隔开。
启动
最后再启动服务。浏览器输入http://localhost:3000/swagger/#/就可以看到swagger文档了
仓库代码