运用Swagger编写API文档
1.Swagger简介
1.1什么是Swagger
随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染、前后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。
前端和后端的唯一联系,变成了API接口;API文档成了前后端开发人员联系的纽带,变得越来越重要,swagger
就是一款让你更好的书写API文档的框架。
1.2 Swagger Editor安装与启动
(1)下载 https://github.com/swagger-api/swagger-editor/releases/download/v2.10.4/swagger-editor.zip。我在资源中已经提供。
(2)解压swagger-editor
(3)全局安装http-server(http-server是一个简单的零配置命令行http服务器)
npm install -g http-server
(4)启动swagger-editor 启动时,CMD位置必须在swagger-editor文件夹的父目录中,如下:
http-server swagger-editor
(5)浏览器打开: http://localhost:8080
1.3 Swagger语法规则
1.3.1字段类型与格式定义
普通的名字 | type | format | 说明 |
---|---|---|---|
integer | integer | int32 | 签署了32位 |
long | integer | int64 | 签署了64位 |
float | number | float | |
double | number | double | |
string | string | ||
byte | string | byte | base64编码的字符 |
binary | string | binary | 任何的八位字节序列 |
boolean | boolean | ||
date | string | date | 所定义的full-date- - - - - -RFC3339 |
dateTime | string | date-time | 所定义的date-time- - - - - -RFC3339 |
password | string | password | 用来提示用户界面输入需要模糊。 |
1.3.2固定字段
字段名 | 类型 | 描述 |
---|---|---|
swagger | string | 必需的。使用指定的规范版本。 |
info | Info Object | 必需的。提供元数据API。 可以使用元数据的客户如果需要。 |
host | string | 主机名或ip服务API。 |
basePath | string | API的基本路径,这是相对的host。 如果不包括,API是直属host。 必须从价值领先斜杠(/)。 的basePath不支持路径模板。 |
schemes | [string] | API的传输协议。 值必须从列表中:“http”,“https”,“ws”,“wss”。 如果schemes不包括,默认使用计划是用于访问大摇大摆的定义本身。 |
consumes | [string] | 一个MIME类型的api可以使用列表。 这是可以覆盖全球所有API,但在特定的API调用。 值必须是所描述的Mime类型。 |
produces | [string] | MIME类型的api可以产生的列表。 这是可以覆盖全球所有API,但在特定的API调用。 值必须是所描述的Mime类型。 |
paths | 路径对象 | 必需的。可用的路径和操作的API。 |
definitions | 定义对象 | 一个对象数据类型生产和使用操作。 |
parameters | 参数定义对象 | 一个对象来保存参数,可以使用在操作。 这个属性不为所有操作定义全局参数。 |
responses | 反应定义对象 | 一个对象响应,可以跨操作使用。 这个属性不为所有操作定义全球响应。 |
securityDefinitions | 安全定义对象 | 安全方案定义规范,可以使用。 |
security | (安全需求对] | 声明的安全计划申请API作为一个整体。 值的列表描述替代安全方案,可以使用(也就是说,有一个逻辑或安全需求之间)。 个人业务可以覆盖这个定义。 |
tags | (标签对] | 的列表标签使用的规范与额外的元数据。 标签的顺序可以用来反思他们的订单的解析工具。 并不是所有使用的标签操作对象必须声明。 声明的标签不可能组织随机或基于工具的逻辑。 列表中的每个标记名称必须是唯一的。 |
externalDocs | 外部文档对象 | 额外的外部文档。 |
tags | (string] | 的标签列表API文档控制。 标签可用于逻辑分组业务的资源或任何其他限定符。 |
summary | string | 什么操作的一个简短的总结。 最大swagger-ui可读性,这一领域应小于120个字符。 |
description | string | 详细解释操作的行为。GFM语法可用于富文本表示。 |
externalDocs | 外部文档对象 | 额外的外部文档操作。 |
operationId | string | 独特的字符串用于识别操作。 id必须是唯一的在所有业务中所描述的API。 工具和库可以使用operationId来唯一地标识一个操作,因此,建议遵循通用的编程的命名约定。 |
consumes | [string] | MIME类型的列表操作可以使用。 这将覆盖consumes定义在炫耀的对象。 空值可用于全球定义清楚。 值必须是所描述的Mime类型。 |
produces | [string] | MIME类型的列表操作可以产生。 这将覆盖produces定义在炫耀的对象。 空值可用于全球定义清楚。 值必须是所描述的Mime类型。 |
parameters | (参数对象 |引用对象] | 适用于该操作的参数列表。 如果已经定义了一个参数道路项目新定义将覆盖它,但不能删除它。 必须不包含重复的参数列表。 一个独特的参数定义的组合的名字和位置。 可以使用列表引用对象链接到参数的定义的对象的参数。 可以有一个“身体”参数。 |
responses | 响应对象 | 必需的。返回的列表可能的反应,因为他们执行这个操作。 |
schemes | [string] | 传输协议的操作。 值必须从列表中:“http”,“https”,“ws”,“wss”。 的值将覆盖的对象schemes定义。 |
deprecated | boolean | 声明该操作被弃用。 使用声明的操作应该没有。 默认值是false。 |
security | (安全需求对] | 声明的安全计划申请这个操作。 值的列表描述替代安全方案,可以使用(也就是说,有一个逻辑或安全需求之间)。 这个定义覆盖任何宣布顶级security。 删除一个顶级安全声明,可以使用一个空数组。 |
2.基础模块API
2.1城市API
2.1.1新增城市
swagger: "2.0"
info:
description: "城市"
version: "1.0.0"
title: "Swagger Petstore"
host: "petstore.swagger.io"
basePath: "/api"
schemes:
- "http"
paths:
'/city':
post:
summary: "增加城市"
description: "增加城市,返回是否成功"
operationId: "addCity"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: successful operation
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
definitions:
City:
type: "object"
properties:
id:
type: "string"
description: "ID"
name:
type: "string"
description: "城市名称"
ishot:
type: "string"
description: "是否热门"
xml:
name: "City"
ApiResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
编辑后可以在右侧窗口看到显示的效果:
2.1.2返回城市列表
(1)在definitions下定义城市列表对象以及相应对象
CityList:
type: "array"
items:
$ref: '#/definitions/City'
ApiCityListResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
data:
$ref: '#/definitions/CityList'
(2)在/city增加get
get:
summary: "城市全部列表"
description: "返回城市全部列表"
operationId: "findCityList"
produces:
- "application/json"
responses:
200:
description: "成功查询到数据"
schema:
$ref: '#/definitions/ApiCityListResponse'
405:
description: "Invalid input"
2.1.3根据ID查询城市
(1)在definitions下定义城市对象的响应对象
ApiCityResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
data:
$ref: '#/definitions/City'
(2)新增/city/{cityId} ,设置get方法API
'/city/{cityId}':
get:
summary: 根据ID查询
description: 返回一个城市
operationId: getCityById
produces:
- application/json
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
responses:
'200':
description: 操作成功
schema:
$ref: '#/definitions/City'
'404':
description: 没找到城市
2.1.4修改城市
/city/{cityId} 下增加put
put:
summary: "修改城市"
description: "修改城市,返回是否成功"
operationId: "updateCity"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
- name: "body"
in: "body"
description: ""
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: "修改成功"
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "输入无效"
2.1.5删除城市
/city/{cityId} 下增加delete
delete:
summary: 根据ID删除
description: 返回是否成功
operationId: deleteCityById
produces:
- application/json
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
responses:
'200':
description: 操作成功
schema:
$ref: '#/definitions/ApiResponse'
'404':
description: 没找到城市
2.1.6城市分页列表
(1)在definitions下定义城市分页列表响应对象
ApiCityPageResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
data:
properties:
total:
type: "integer"
format: "int32"
rows:
$ref: '#/definitions/CityList'
(2)新增节点
'/city/search/{page}/{size}':
post:
summary: "城市分页"
description: "显示城市分页数据"
operationId: "cityPage"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: "页码"
required: true
type: integer
format: int64
- name: "body"
in: "body"
description: "查询条件"
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiCityPageResponse'
405:
description: "Invalid input"
最终完整的Swagger文档如下:
swagger: "2.0"
info:
description: "城市"
version: "1.0.0"
title: "十次方API列表-城市"
host: "petstore.swagger.io"
basePath: "/api"
schemes:
- "http"
paths:
'/city':
post:
summary: "增加城市"
description: "增加城市,返回是否成功"
operationId: "addCity"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: successful operation
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
get:
summary: "城市全部列表"
description: "返回城市全部列表"
operationId: "findCityList"
produces:
- "application/json"
responses:
200:
description: "成功查询到数据"
schema:
$ref: '#/definitions/ApiCityListResponse'
405:
description: "Invalid input"
'/city/{cityId}':
get:
summary: 根据ID查询
description: 返回一个城市
operationId: getCityById
produces:
- application/json
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
responses:
'200':
description: 操作成功
schema:
$ref: '#/definitions/ApiCityResponse'
'404':
description: 没找到城市
put:
summary: "修改城市"
description: "修改城市,返回是否成功"
operationId: "updateCity"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
- name: "body"
in: "body"
description: ""
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: "修改成功"
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "输入无效"
delete:
summary: 根据ID删除
description: 返回是否成功
operationId: deleteCityById
produces:
- application/json
parameters:
- name: cityId
in: path
description: 城市ID
required: true
type: integer
format: int64
responses:
'200':
description: 操作成功
schema:
$ref: '#/definitions/ApiResponse'
'404':
description: 没找到城市
'/city/search/{page}/{size}':
post:
summary: "城市分页"
description: "显示城市分页数据"
operationId: "cityPage"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: "页码"
required: true
type: integer
format: int64
- name: "body"
in: "body"
description: "查询条件"
required: true
schema:
$ref: "#/definitions/City"
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiCityPageResponse'
405:
description: "Invalid input"
definitions:
City:
type: "object"
properties:
id:
type: "string"
description: "ID"
name:
type: "string"
description: "城市名称"
ishot:
type: "string"
description: "是否热门"
xml:
name: "City"
CityList:
type: "array"
items:
$ref: '#/definitions/City'
ApiResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
ApiCityResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
data:
$ref: '#/definitions/City'
ApiCityListResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
flag:
type: "boolean"
message:
type: "string"
data:
$ref: '#/definitions/CityList'
ApiCityPageResponse:
type: "object"
properties:
code:
type: "integer"
format: "int64"
flag:
type: "boolean"
message:
type: "string"
data:
properties:
total:
type: "integer"
format: "int32"
rows:
$ref: '#/definitions/CityList'
2.1 数据库建表
打开数据库,点击运行sql文件,打开 "课前资料\资源\建表语句"中的sql文件,逐个运行,建立数据库,建立成功后效果如下图:
2.3代码生成器批量生成
我们通过代码生成器自动生成所有表的yml文档,步骤如下:
2.3.1 解压代码生成器
将 课前资料\资源\代码生成器\HeimaCodeUtil_V2.4_64.zip 解压到任意目录,注意,目录名称不允许有中文和特殊字符,否则会导致生成失效.
2.3.1 批量生成API文档代码
打开代码生成器,按如下步骤进行操作:
点击 生成代码 后,可以看到效果如下:
打开yml文档,我们会发现自动生成的文档中类型均为string ,我们这里需要再对类型进行修改即可。
其他模块API大家参考笔记 3,4,5项即可,这里我们不再演示。
完整的swagger API文档在 …课前资料\资源\API文档\nginx_api.zip\nginx-1.13.12\html\api
2.4标签API
学员实现,代码略
3.用户模块API
3.1用户API
使用代码生成器生成后,右键打开,粘贴代码到swagger-editor,进行修改和编辑
3.1.1修改User实体定义
User:
type: "object"
properties:
id:
type: "string"
description: "ID"
loginname:
type: "string"
description: "登陆名"
password:
type: "string"
description: "密码"
nickname:
type: "string"
description: "昵称"
sex:
type: "string"
description: "性别"
birthday:
type: "string"
format: 'date-time'
description: "出生年月日"
image:
type: "string"
description: "头像"
mobile:
type: "string"
description: "手机号码"
email:
type: "string"
description: "E-Mail"
regdate:
type: "string"
format: 'date'
description: "注册日期"
updatedate:
type: "string"
description: "修改日期"
format: 'date'
lastdate:
type: "string"
description: "最后登陆日期"
format: 'date'
online:
type: "integer"
format: 'int64'
description: "在线时长(分钟)"
interest:
type: "string"
description: "兴趣"
personality:
type: "string"
description: "个性"
fanscount:
type: "integer"
description: "粉丝数"
format: 'int64'
followcount:
type: "integer"
description: "关注数"
format: 'int64'
3.1.2发送手机验证码
修改user.yml ,增加
/sendsms/{mobile}:
get:
summary: "发送手机验证码"
description: "发送手机验证码"
operationId: "sendsms"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: mobile
in: path
description: 手机号
required: true
type: integer
format: int64
responses:
200:
description: 发送成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
3.1.3用户上传头像
/user/upload:
post:
summary: 上传头像
description: 上传头像
consumes:
- "multipart/form-data"
parameters:
- name: file
in: formData
required: true
type: file
responses:
200:
description: OK
schema:
$ref: '#/definitions/ApiResponse'
3.1.4关注和取消关注某用户
/user/follow/{userId}:
put:
summary: "关注某用户"
description: "关注某用户"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: userId
in: path
required: true
type: string
responses:
200:
description: OK
schema:
$ref: '#/definitions/ApiResponse'
delete:
summary: 删除某用户关注
description: 删除某用户关注
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: userId
in: path
required: true
type: string
responses:
200:
description: OK
schema:
$ref: '#/definitions/ApiResponse'
3.1.6查询我的粉丝
/user/follow/myfans:
get:
summary: "查询我的粉丝"
description: "查询我的粉丝"
consumes:
- "application/json"
produces:
- "application/json"
responses:
200:
description: OK
schema:
$ref: '#/definitions/ApiUserListResponse'
3.1.7查询我的关注ID列表
增加对象定义:
UserIdList:
type: "array"
items:
type: "string"
ApiUserIdListResponse:
type: "object"
properties:
code:
type: "integer"
format: "int64"
flag:
type: "boolean"
message:
type: "string"
data:
$ref: "#/definitions/UserIdList"
增加方法:
/user/follow/myfollowid:
get:
summary: "查询我的关注ID列表"
description: "查询我的关注ID"
consumes:
- "application/json"
produces:
- "application/json"
responses:
200:
description: OK
schema:
$ref: '#/definitions/ApiUserIdListResponse'
3.2管理员API
学员实现(代码略)
4.问答模块API
4.1问题API
4.1.1根据标签ID查询问题
/problem/label/{label}/{page}/{size}:
post:
summary: Problem分页
description: 显示Problem分页数据
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: label
in: path
description: 标签ID
required: true
type: integer
format: int64
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: 页码
required: true
type: integer
format: int64
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiProblemPageResponse'
405:
description: "Invalid input"
4.1.2提出问题
/problem/save:
post:
summary: Problem分页
description: 显示Problem分页数据
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: "#/definitions/Problem"
responses:
200:
description: successful operation
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
4.1.3我的问题列表
/problem/list/{page}/{size}:
get:
summary: 我的问题列表
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: 页码
required: true
type: integer
format: int64
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiProblemPageResponse'
405:
description: "Invalid input"
4.2回答API
4.2.1根据问题ID查询回答列表
修改reply.yml实体定义
Reply:
type: "object"
properties:
id:
type: "string"
description: "编号"
problemid:
type: "string"
description: "问题ID"
content:
type: "string"
description: "回答内容"
createtime:
type: "string"
description: "创建日期"
format: date
updatetime:
type: "string"
description: "更新日期"
format: date
userid:
type: "string"
description: "回答人ID"
nikename:
type: "string"
description: "回答人昵称"
增加地址:
/reply/problem/{problemId}:
get:
summary: "根据问题ID查询回答列表"
description: "根据问题ID查询回答列表"
produces:
- "application/json"
parameters:
- name: problemId
in: path
description: "问题ID"
required: true
type: integer
format: int64
responses:
200:
description: "成功查询到数据"
schema:
$ref: '#/definitions/ApiReplyListResponse'
405:
description: "Invalid input"
4.2.2我的回答列表
/reply/list/{page}/{size}:
get:
summary: "我的回答列表"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: "页码"
required: true
type: integer
format: int64
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiReplyPageResponse'
405:
description: "Invalid input"
5.文章模块API
5.1专栏API
5.1.1修改专栏实体
Column:
type: "object"
properties:
id:
type: "string"
description: "ID"
name:
type: "string"
description: "专栏名称"
summary:
type: "string"
description: "专栏简介"
userid:
type: "string"
description: "用户ID"
createtime:
type: "string"
description: "申请日期"
format: date
checktime:
type: "string"
description: "审核日期"
format: date
state:
type: "string"
description: "状态"
5.1.2申请专栏
'/column/apply':
post:
summary: "专栏申请"
description: "专栏申请"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: "#/definitions/Column"
responses:
200:
description: 申请成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: 无效输入
5.1.3专栏审核
/column/examine/{columnId}:
put:
summary: "申请审核"
description: "专栏审核"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "columnId"
in: "path"
description: "专栏ID"
required: true
type: string
responses:
200:
description: 申请成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: 无效输入
5.1.4根据用户获取专栏列表
/column/user/{userId}:
get:
summary: "根据用户ID查询专栏列表"
description: "根据用户ID查询专栏列表"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "userId"
in: "path"
description: "用户Id"
required: true
type: string
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiColumnListResponse'
405:
description: 无效输入
5.2文章API
5.2.1修改文章实体
修改article.yml中的实体定义
Article:
type: "object"
properties:
id:
type: "string"
description: "ID"
columnid:
type: "string"
description: "专栏ID"
userid:
type: "string"
description: "用户ID"
title:
type: "string"
description: "标题"
content:
type: "string"
description: "文章正文"
image:
type: "string"
description: "文章封面"
createtime:
type: "string"
description: "发表日期"
format: date
updatetime:
type: "string"
description: "修改日期"
format: date
ispublic:
type: "string"
description: "是否公开"
istop:
type: "string"
description: "是否置顶"
visits:
type: "integer"
description: "浏览量"
format: int64
thumbup:
type: "integer"
description: "点赞数"
format: int64
comment:
type: "integer"
description: "评论数"
format: int64
state:
type: "string"
description: "审核状态"
channelid:
type: "integer"
description: "所属频道"
format: int64
url:
type: "string"
description: "URL"
type:
type: "string"
description: "类型"
5.2.2发表文章
/article/save:
post:
summary: "发表文章"
description: "发表文章"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: ""
required: true
schema:
$ref: "#/definitions/Article"
responses:
200:
description: 发表成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
5.2.3文章点赞
/article/thumbup/{articleId}:
put:
summary: "点赞"
description: "点赞"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "articleId"
in: "path"
description: ""
required: true
type: string
responses:
200:
description: 操作成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
5.2.4根据频道ID获取文章列表
'/article/channel/{channelId}/{page}/{size}':
post:
summary: "根据频道ID获取文章列表"
description: "根据频道ID获取文章列表"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: "页码"
required: true
type: integer
format: int64
- name: "channelId"
in: "path"
description: "频道ID"
required: true
type: "integer"
format: int64
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiArticlePageResponse'
405:
description: "Invalid input"
5.2.5根据专栏ID获取文章列表
'/article/column/{columnId}/{page}/{size}':
post:
summary: "根据专栏ID获取文章列表"
description: "根据专栏ID获取文章列表"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: page
in: path
description: 页码
required: true
type: integer
format: int64
- name: size
in: path
description: "页码"
required: true
type: integer
format: int64
- name: "columnId"
in: "path"
description: "专栏ID"
required: true
type: "integer"
format: int64
responses:
200:
description: 查询成功
schema:
$ref: '#/definitions/ApiArticlePageResponse'
405:
description: "Invalid input"
5.2.6文章审核
/article/examine/{articleId}:
put:
summary: "文章审核"
description: "文章审核"
parameters:
- name: articleId
in: path
description: 文章ID
required: true
type: integer
format: int64
responses:
200:
description: 操作成功
schema:
$ref: '#/definitions/ApiResponse'
405:
description: "Invalid input"
5.2.7头条文章
/article/top:
get:
summary: "头条文章"
description: "头条文章"
produces:
- "application/json"
responses:
200:
description: "成功查询到数据"
schema:
$ref: '#/definitions/ApiArticleListResponse'
405:
description: "Invalid input"
6.SwaggerUI
SwaggerUI是用来展示Swagger文档的界面,以下为安装步骤
(1)在本地安装nginx
(2)下载SwaggerUI源码 https://swagger.io/download-swagger-ui/
(3)解压swagger-ui-master.zip(课前资料\资源\配套软件) ,将dist文件夹下的全部文件拷贝至 nginx的html目录
(4)启动nginx
(5)浏览器打开页面 http://localhost即可看到文档页面
(6)我们将编写好的yml文件也拷贝至nginx的html目录,这样我们就可以加载我们的
swagger文档了
7.Mock.js
7.1 Mock.js介绍以及特点
7.1.1介绍:
Mock.js (官网http://mockjs.com/)是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:
根据数据模板生成模拟数据,
模拟 Ajax 请求,生成并返回模拟数据,
基于 HTML 模板生成模拟数据
7.1.2Mock.js特点:
1.前后端分离,让前端工程师独立于后端进行开发。
2.通过随机数据,模拟各种场景,增加单元测试的真实性
3.开发无侵入
4.不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
5.用法简单,方便扩展
6.数据类型丰富
7.支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
8.支持支持扩展更多数据类型,支持自定义函数和正则。
7.2 Mock.js安装
在工作目录下新建文件夹,比如mockdemo,进入该文件夹,执行如下命令,
在命令提示符下用npm安装mockjs
cnpm install mockjs
7.3 快速入门
需求:生成列表数据,数据条数为5条。
显示效果如下:
{"list": [
{
"id": 1,
"name": "测试"
},{
"id": 1,
"name": "测试"
},{
"id": 1,
"name": "测试"
},{
"id": 1,
"name": "测试"
},{
"id": 1,
"name": "测试"
}
]}
新建在mockdemo文件夹下新建demo1.js 代码如下
//生成json格式的列表数据,包含五条数据,数据对象包含id name属性
let mock = require('mockjs');
let data = mock.mock({
"list|5":[{
"id":1,
"name":"test"
}]
});
console.log(JSON.stringify(data));
终端使用执行命令 node demo1 查看运行效果:
我们在本例中产生了5条相同的数据,这些数据都是相同的,如果我们需要让这些数据是按照一定规律随机生成的,需要按照Mock.js的语法规范来定义。
Mock.js 的语法规范包括两部分:
1.数据模板定义规范(Data Template Definition,DTD)
2.数据占位符定义规范(Data Placeholder Definition,DPD)
7.4 数据模板定义规范DTD
数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值
// 属性名 name
// 生成规则 rule
// 属性值 value 'name|rule': value
7.4.1 属性名和生成规则
属性名 和 生成规则 之间用竖线 | 分隔。
生成规则 是可选的,生成规则 有 7 种格式,如下:
‘name|min-max’: value
‘name|count’: value
‘name|min-max.dmin-dmax’: value
‘name|min-max.dcount’: value
‘name|count.dmin-dmax’: value
‘name|count.dcount’: value
‘name|+step’: value
生成规则的含义需要依赖属性值的类型才能确定。
7.4.2 属性值
属性值 中可以含有 @占位符。属性值 还指定了最终值的初始值和类型
7.4.2.1 属性值是字符串
(1)‘name|count’: string
通过重复 string 生成一个字符串,重复次数等于 count,代码如下:
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5': [{
'id': 1,
'name':'测试',
'phone|11':'1'
}]
})
// 输出结果
console.log(JSON.stringify(data,null,2));
运行结果如下:
(2)‘name|min-max’: string
通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max.
代码和运行结果如下:
7.4.2.2 属性值是数字number
(1)‘name|+1’: number
属性值自动加 1,初始值为 number。
(2)‘name|min-max’: number
生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型
(3)‘name|min-max.dcount’: value 生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分为dcount位
(4)‘name|min-max.dmin-dmax’: number
生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分保留 dmin 到 dmax 位。
7.4.2.3 属性值是布尔
(1)‘name|1’: boolean
随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2
(2)‘name|min-max’: value
随机生成一个布尔值,值为 value 的概率是 min / (min + max)
7.4.2.4 属性值是Object
(1)‘name|count’: object
从属性值 object 中随机选取 count 个属性。
代码如下:
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5': [{
'id|+1': 1,//指定 +1 后,执行时会基于初始值的基础上递增1
'name|2-4':'测试',
'phone|11':'1',
'point|100-500':0,//添加积分字段,值的范围为大于等于100,小于等于500
'money|1000-5000.2-4':0, //添加钱财字段,该值是浮点数,大于等于1000小于等于5000,且随机保留2-4位小数
'status|1':true,//添加状态字段,值为true或false的概率各为50%
'default|1-3':true,//随机生成default,值为true的概率为 min/(min+max)
'detail|2':{'id':1,'date':'2005‐01‐01','content':'记录'}//从对象中随机选取2个属性
}]
})
// 输出结果
console.log(JSON.stringify(data,null,2));
执行结果如下:
(2)‘name|min-max’: object
从属性值 object 中随机选取 min 到 max 个属性
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5': [{
'id|+1': 1,//指定 +1 后,执行时会基于初始值的基础上递增1
'name|2-4':'测试',
'phone|11':'1',
'point|100-500':0,//添加积分字段,值的范围为大于等于100,小于等于500
'money|1000-5000.2-4':0, //添加钱财字段,该值是浮点数,大于等于1000小于等于5000,且随机保留2-4位小数
'status|1':true,//添加状态字段,值为true或false的概率各为50%
'default|1-3':true,//随机生成default,值为true的概率为 min/(min+max)
'detail|2-3':{'id':1,'date':'2005‐01‐01','content':'记录'}//从对象中随机选取2-3个属性
}]
})
// 输出结果
console.log(JSON.stringify(data,null,2));
执行结果如下:
7.4.2.5 属性值是数组
(1)‘name|count’: array
通过重复属性值 array 生成一个新数组,重复次数为 count
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5': [{ //重复生成5个数组
'id|+1': 1,
'name|2-4':'测试',
'phone|11':'1'
}]
})
// 输出结果
console.log(JSON.stringify(data,null,2));
(2)‘name|min-max’: array
通过重复属性值 array 生成一个新数组,重复次数大于等于 min,小于等于 max。
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5-10': [{ //重复生成5-10个数组
'id|+1': 1,
'name|2-4':'测试',
'phone|11':'1'
}]
})
// 输出结果
console.log(JSON.stringify(data,null,2));
7.5 数据占位符定义规范DPD
Mock.Random 是一个工具类,用于生成各种随机数据。
Mock.Random 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数 [, 参数]) 。
内置方法列表:
下面我们讲解每种内置方法的使用.
7.5.1 基本方法
可以生成随机的基本数据类型
string 字符串
integer 整数
date 日期
代码如下:
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5-10': [{
'id|+1': 1,
'name':'@string',
'phone':'@integer',
'birthday':'@date'
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出结果如下:
3.5.2 图像方法
image 随机生成图片地址
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5-10': [{
'id|+1': 1,
'name':'@string',
'phone':'@integer',
'birthday':'@date',
'pic':'@image'
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出如下:
3.5.3 文本方法
@title: 标题
@cword(100) :文本内容 参数为字数
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5-10': [{
'id|+1': 1,
'name':'@string',
'phone':'@integer',
'birthday':'@date',
'pic':'@image',
'title':'@title',
'content':'@cword(100)'
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出结果如下:
7.5.2 名称方法
cname :中文名称
cfirst:中文姓氏
Last:英文姓氏
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|5-10': [{
'id|+1': 1,
'name':'@cname',
'ename':'@last',
'cfirst':'@cfirst',
'phone':'@integer',
'birthday':'@date',
'pic':'@image',
'title':'@title',
'content':'@cword(100)'
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出结果如下:
7.5.3 网络方法
可以生成url ip email等网络相关信息
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|1-3': [{
'id|+1': 1,
'name':'@cname',
'ename':'@last',
'cfirst':'@cfirst',
'phone':'@integer',
'birthday':'@date',
'pic':'@image',
'title':'@title',
'content':'@cword(100)',
'url':"@url",
'ip':"@ip",
'email':"@email"
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出结果如下:
7.5.4 地址方法
@region 区域
@county 省市县
代码如下:
// 使用 Mock
let Mock = require('mockjs')
let data = Mock.mock({
'list|1-3': [{
'id|+1': 1,
'name':'@cname',
'ename':'@last',
'cfirst':'@cfirst',
'phone':'@integer',
'birthday':'@date',
'pic':'@image',
'title':'@title',
'content':'@cword(100)',
'url':"@url",
'ip':"@ip",
'email':"@email",
'area':'@region',
'address':'@county(true)'
}]})
// 输出结果
console.log(JSON.stringify(data,null,2));
输出结果如下:
8 EasyMock
8.1 什么是EasyMock
Easy Mock 是杭州大搜车无线团队出品的一个极其简单、高效、可视化、并且能快速生成模拟数据的 在线 mock 服务 。以项目管理的方式组织 Mock List,能帮助我们更好的管理 Mock 数据。
在线文档:https://www.easy-mock.com/docs
8.2 EasyMock基本入门
8.2.1初始设置
(1)登录或注册。
浏览器打开https://www.easy-mock.com 输出用户名和密码,如果不存在会自动注册。注意:请牢记密码,系统没有找回密码功能!
登录后进入主界面
![img](file:///C:\md\images\wps8092.tmp.png)
(2)创建项目:点击右下角的加号
填写项目名称,点击创建按钮
![img](file:///C:\md\images\wps80A5.tmp.png)
创建完成后可以在列表中看到刚刚创建的项目
8.2.2接口操作
(1)创建接口。点击列表中的项目
![img](file:///C:\md\images\wps80B8.tmp.png)
进入项目工作台页面
![img](file:///C:\md\images\wps80B9.tmp.png)
点击“创建接口” ,左侧区域输出mock数据,右侧定义Method 、 Url 、描述等信息。
我们可以将我们在Mock.js入门案例中的对象放入左侧的编辑窗口
{
'list|1-3': [{
'id|+1': 1,
'name':'@cname',
'ename':'@last',
'cfirst':'@cfirst',
'phone':'@integer',
'birthday':'@date',
'pic':'@image',
'title':'@title',
'content':'@cword(100)',
'url':"@url",
'ip':"@ip",
'email':"@email",
'area':'@region',
'address':'@county(true)'
}]}
填写url Method 和描述 ,点击创建按钮
(2)克隆接口和修改接口
参照页面点击即可
(3)预览接口和复制接口地址
参照页面点击即可
(4)删除接口
参照页面点击即可
8.3 本地部署EasyMock
将接口放在在线的EasyMock网站中,无形中形成了对该网站的依赖,如果该网站宕机或无法访问,我们的接口也就作废了,所以我们需要将EasyMock本地化,部署到局域网的某台服务器中。
我们将EasyMock本地部署需要将其按照在Centos中,EasyMock使用了Node.js ,MongoDB,Redis,我们需要逐个安装配置,才能实现EasyMock的本地化部署。
课前资料\资源\镜像\centos7.zip中虚拟机镜像的登录用户名:root 密码:itcast
如果镜像用vmvare打开有如下弹窗:
将解压的centos7镜像中使用编辑器打开CentOS 64 位.vmx,修改如下:
8.3.1 Centos部署node.js
(1)将node官网下载的 课前资料\资源\配套软件\node.js\node-v8.11.1-linux-x64.tar.xz 上传至服务器
(2)解压xz文件
xz ‐d node‐v8.11.1‐linux‐x64.tar.xz
(3)解压tar文件
tar ‐xvf node‐v8.11.1‐linux‐x64.tar
(4)目录重命名
mv node‐v8.11.1‐linux‐x64 node
(5)移动目录到/usr/local下
mv node /usr/local/
(6)配置环境变量
vi /etc/profile
填写以下内容
#set for nodejs
export NODE_HOME=/usr/local/node
export PATH=$NODE_HOME/bin:$PATH
执行命令让环境变量生效
source /etc/profile
查看node版本看是否安装成功
node ‐v
8.3.2 MongoDB安装与启动
我们使用yum方式安装mongoDb
(1)配置yum
vi /etc/yum.repos.d/mongodb‐org‐3.2.repo
编辑以下内容:
[mongodb‐org‐3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb‐org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server‐3.2.asc
(2)安装MongoDB
yum install ‐y mongodb‐org
(3)启动MongoD
systemctl start mongod
注意启动时是mongd, 不是mongodb
8.3.3 Redis安装与启动
(1)下载fedora的epel仓库
yum install epel‐release
(2)下载安装redis
yum install redis
(3)启动redis服务
systemctl start redis
8.3.4 本地部署easy-mock
(1)项目下载地址: https://github.com/easy-mock/easy-mock
(2)将easy-mock-dev.zip上传至服务器
(3)安装zip 和unzip
yum install zip unzip
(4)解压
unzip easy‐mock‐dev.zip
(3)进入其目录,安装依赖
npm install
(4)执行构建
npm run build
(5)启动
npm run start
(6)打开浏览器 http://192.168.184.131:7300
如果无法访问,需要关闭centos7的防火墙,执行命令如下:
systemctl stop firewalld.service
然后重新启动EasyMock即可
![img](file:///C:\md\images\wps8125.tmp.png)
8.4 导入SwaggerAPI文档
(1)将我们的SwaggerAPI文档扩展名改为yml
(2)在easyMock中点击“设置”选项卡
(3)SwaggerDocs API 选择Upload
(4)将SwaggerAPI文档拖动到上图的虚线区域,点击保存
(5)回到主界面后点击“同步Swagger”