swagger.md

运用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文件夹的父目录中,如下:

52947522722

http-server swagger-editor

(5)浏览器打开: http://localhost:8080

52947537183

1.3 Swagger语法规则

1.3.1字段类型与格式定义

普通的名字typeformat说明
integerintegerint32签署了32位
longintegerint64签署了64位
floatnumberfloat
doublenumberdouble
stringstring
bytestringbytebase64编码的字符
binarystringbinary任何的八位字节序列
booleanboolean
datestringdate所定义的full-date- - - - - -RFC3339
dateTimestringdate-time所定义的date-time- - - - - -RFC3339
passwordstringpassword用来提示用户界面输入需要模糊。

1.3.2固定字段

字段名类型描述
swaggerstring必需的。使用指定的规范版本。
infoInfo Object必需的。提供元数据API。 可以使用元数据的客户如果需要。
hoststring主机名或ip服务API。
basePathstringAPI的基本路径,这是相对的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文档控制。 标签可用于逻辑分组业务的资源或任何其他限定符。
summarystring什么操作的一个简短的总结。 最大swagger-ui可读性,这一领域应小于120个字符。
descriptionstring详细解释操作的行为。GFM语法可用于富文本表示。
externalDocs外部文档对象额外的外部文档操作。
operationIdstring独特的字符串用于识别操作。 id必须是唯一的在所有业务中所描述的API。 工具和库可以使用operationId来唯一地标识一个操作,因此,建议遵循通用的编程的命名约定。
consumes[string]MIME类型的列表操作可以使用。 这将覆盖consumes定义在炫耀的对象。 空值可用于全球定义清楚。 值必须是所描述的Mime类型。
produces[string]MIME类型的列表操作可以产生。 这将覆盖produces定义在炫耀的对象。 空值可用于全球定义清楚。 值必须是所描述的Mime类型。
parameters(参数对象 |引用对象]适用于该操作的参数列表。 如果已经定义了一个参数道路项目新定义将覆盖它,但不能删除它。 必须不包含重复的参数列表。 一个独特的参数定义的组合的名字和位置。 可以使用列表引用对象链接到参数的定义的对象的参数。 可以有一个“身体”参数。
responses响应对象必需的。返回的列表可能的反应,因为他们执行这个操作。
schemes[string]传输协议的操作。 值必须从列表中:“http”,“https”,“ws”,“wss”。 的值将覆盖的对象schemes定义。
deprecatedboolean声明该操作被弃用。 使用声明的操作应该没有。 默认值是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文件,逐个运行,建立数据库,建立成功后效果如下图:

52967122156

2.3代码生成器批量生成

我们通过代码生成器自动生成所有表的yml文档,步骤如下:

2.3.1 解压代码生成器

将  课前资料\资源\代码生成器\HeimaCodeUtil_V2.4_64.zip 解压到任意目录,注意,目录名称不允许有中文和特殊字符,否则会导致生成失效.

2.3.1 批量生成API文档代码

​ 打开代码生成器,按如下步骤进行操作:

52967157439

52967165720

点击 生成代码 后,可以看到效果如下:

52967169100

打开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即可看到文档页面

52967235573

(6)我们将编写好的yml文件也拷贝至nginx的html目录,这样我们就可以加载我们的
swagger文档了

52967238927

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 查看运行效果:

52972208192

我们在本例中产生了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));

运行结果如下:

52972313603

(2)‘name|min-max’: string

通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max.

代码和运行结果如下:

52972339410

7.4.2.2 属性值是数字number

(1)‘name|+1’: number

属性值自动加 1,初始值为 number。

52972449301

(2)‘name|min-max’: number

生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型

52972476193

(3)‘name|min-max.dcount’: value 生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分为dcount位

52972496579

(4)‘name|min-max.dmin-dmax’: number

生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分保留 dmin 到 dmax 位。

52972506695

7.4.2.3 属性值是布尔

(1)‘name|1’: boolean

随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2

52972536874

(2)‘name|min-max’: value

随机生成一个布尔值,值为 value 的概率是 min / (min + max)

52972560593

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));

执行结果如下:

52972584841

(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));

执行结果如下:

52972596262

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 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数 [, 参数]) 。

内置方法列表:

52972628138

下面我们讲解每种内置方法的使用.

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));

输出结果如下:

52972670730

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));

输出如下:

52972717718

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));

输出结果如下:

52973134833

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));

输出结果如下:

52973164157

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));

输出结果如下:

52973212978

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));

输出结果如下:

52973236859

8 EasyMock

8.1 什么是EasyMock

Easy Mock 是杭州大搜车无线团队出品的一个极其简单、高效、可视化、并且能快速生成模拟数据的 在线 mock 服务 。以项目管理的方式组织 Mock List,能帮助我们更好的管理 Mock 数据。

地址:https://www.easy-mock.com

在线文档:https://www.easy-mock.com/docs

8.2 EasyMock基本入门

8.2.1初始设置

(1)登录或注册。

浏览器打开https://www.easy-mock.com 输出用户名和密码,如果不存在会自动注册。注意:请牢记密码,系统没有找回密码功能!

img

登录后进入主界面

![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)'
 }]}

52973371043

​ 填写url Method 和描述 ,点击创建按钮

(2)克隆接口和修改接口

​ 参照页面点击即可

(3)预览接口和复制接口地址

  参照页面点击即可

(4)删除接口

  参照页面点击即可

8.3 本地部署EasyMock

将接口放在在线的EasyMock网站中,无形中形成了对该网站的依赖,如果该网站宕机或无法访问,我们的接口也就作废了,所以我们需要将EasyMock本地化,部署到局域网的某台服务器中。

我们将EasyMock本地部署需要将其按照在Centos中,EasyMock使用了Node.js ,MongoDB,Redis,我们需要逐个安装配置,才能实现EasyMock的本地化部署。

课前资料\资源\镜像\centos7.zip中虚拟机镜像的登录用户名:root 密码:itcast

如果镜像用vmvare打开有如下弹窗:

52973656855

将解压的centos7镜像中使用编辑器打开CentOS 64 位.vmx,修改如下:

52973665149

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

52974271324

(4)将SwaggerAPI文档拖动到上图的虚线区域,点击保存

(5)回到主界面后点击“同步Swagger”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值