API 文档神器 Swagger 介绍及在 PHP 项目中使用

Stella981
• 阅读 668

Swagger 是我目前用过的最优秀的 Api Doc 协议没有之一。它与其他 Api Doc 协议(如apidocjs)最大的差别在于,Swagger 不仅仅可以定义 Api 的 Route / Request Param 和 Response,还可以定义 Definitions Object / Security Definitions Object 以及 Reference Object

以一个电商项目为例,系统里有 商品(Product)和 订单(Order)两个 Model,其中 Order 有一个 product_id 字段用于关联对应的商品;有两个接口,一个是获取商品详情 /product/{product},另一个是获取订单详情 /order/{order},为了减少Api请求数量,在获取订单详情时我们希望同时返回对应的商品数据。

如果我们用 apidocjs 来写的话,会是类似下面的注释

/**
 * @api {get} /product/:product Request Product information
 * @apiName GetProduct
 * @apiParam {Number} product Products unique ID.
 * @apiSuccess {String} name Name of the Product.
 * @apiSuccess {Number} price  Price of the Product.
 * @apiSuccess ... Others fields
 */
 
 /**
 * @api {get} /order/:order Request Order information
 * @apiName GetOrder
 * @apiParam {Number} order Orders unique ID.
 * @apiHeader {String} Authorization Access Token.
 * @apiSuccess {String} flow_no FlowNo of the Order.
 * @apiSuccess {String} price  Price of the Order.
 * @apiSuccess {Object} product Product of the Order
 * @apiSuccess {String} product.name Name of the Product.
 * @apiSuccess {Number} product.price  Price of the Product.
 * @apiSuccess ... Others fields
 */

可以看到 Product 的字段在两个接口的注释里各写了一遍,这就很繁琐;另外一个更严重的问题是,如果未来 Product 表的字段发生了增减,我们需要去修改每一个会输出 Product 的接口的注释,更繁琐而且容易遗漏。

所以我们需要有一个可以定义 Model 字段的功能,这就是 Swagger 的 Definitions Object,我们事先将 Product 和 Order 定义成 Definitions Object:

Product:
  type: object
  properties:
    id:
      type: integer
    name:
      type: string
       price:
          type: integer

Order:
  type: object
    properties:
      id:
          type: integer
      flow_no:
            type: string
        product:
            $ref: '#/definitions/Product'

在定义 Order 的 product 字段时,我们使用了 $ref,也就是 Reference Object,这就是告诉 Swagger,Order 的product 字段指向了 Product 的定义。

再来看看 Route / Request Param 和 Response 在Swagger 中怎么写:

path:
    /product/{product}:
        get:
            summary: Request Product information
            parameters:
                name: product
                in: path
                required: true
                type: number
            response:
                '200':
                    description: Success
                    schema:
                        $ref: '#/definitions/Product'
    /order/{order}:
        get:
            summary: Request Order information
            parameters:
                name: order
                in: path
                required: true
                type: number
            response:
                '200':
                    description: Success
                    schema:
                        $ref: '#/definitions/Order'

通过 $ref 完美解决了增减字段需要修改多处的问题。

我在第一次使用 Swagger 的时候,虽然被其强大的定义功能所折服,却又对写 Swagger 文档极其的厌恶,因为官方提供的 Swagger Editor 速度不仅慢,还时不时出错,明明写对了文档格式非要告诉我有问题,只能刷新页面重新加载。

直到最近发现了一个项目 swagger-php,通过注释的方式来生成 JSON 格式的 Swagger 文档,只需要通过 \Swagger\scan() 函数扫描一个目录下所有 PHP 文件的注释 (可以创建一个完全只有注释的 php 文件来放一些与 request / response 并无直接关联的定义,比如 Security Definitions Object)。

有了 JSON 格式的文档之后,配合 Swagger UI 就可以展示出非常美观的 Api 文档了,可以看这个 Demo,还支持在文档页面直接发起 Api 请求,大大的方便!

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这