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

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 请求,大大的方便!

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 6年前 加精
leo
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 28

swagger确实方便,还可以发起授权验证等

6年前 评论

这个能跑自动化测试吗?

6年前 评论
leo

@mostwin api 文档做自己该做的事,功能多了反倒不伦不类

6年前 评论

apidocjs 不是可以用 @apiDefine 定义一个块吗?

6年前 评论
leo

@klgd apidocjs 的 Define 和 Swagger 的 Define 完全是两码事

6年前 评论
nickfan

@leo 虽然Swagger 是神器,但我是来歪楼的,:boom:
说好的laravel的cas客户端呢~~~ :pig:

6年前 评论
leo

@nickfan 最近有点倒戈 OAuth 了怎么办

6年前 评论
nickfan

@leo 这两者又不冲突,cas客户端还是要滴啊,
oauth的场景和cas还是有差别的啊。
改个修复已知bug支持laravel的cas客户端还是很有用的哦,嘻嘻~~

6年前 评论

它的官网还真不是一般的慢啊!

6年前 评论

我也是来歪楼的,原来天天看你 github 上 cas client 没动静的不止我一人呢。

6年前 评论
leo

@springjk 没想到这么多人关注,最近有点忙,我尽快……

6年前 评论
宇宙最厉害

:smile: 上个项目就用到这个了,写的挺累的。但是我觉得 Swagger UI 很好看。:+1:

6年前 评论

@leo Leo 总,我最近发布的一个框架PhpBoot,可以完美支持 Swagger,而不用像 swagger-php 一样,增加很多额外的注释。在线 Demo请见在线 Demo,PhpBoot 介绍请见介绍一款【没 Laravel 优雅】也【没有 Laravel 强大】的, 但简单易用的框架

6年前 评论

或者 API Blueprint, https://apiblueprint.org/ ,也是写一个Markdown文档。服务可以使用 Apiary,也不错的api docs管理工具。

file

6年前 评论
dszkng

laravel5.5支持麽

6年前 评论
leo

@dszkng 支持,我们公司的项目就在用

6年前 评论
jcc123

注释生成的配置文件,是通过注册swaggerUI的账号来和项目成员共享API文档吗,还是自己搭建一个可以解析的swaggerUI服务。您推荐哪种方式?

5年前 评论
leo

@jcc123 swaggerUI 就是一堆静态 html 文件,放本地都行

5年前 评论
leung0826

多version,比如: /v1, /v2 ..的文档怎么生成呢?

5年前 评论

@leo 感觉 postman 的 Api doc 也还行

5年前 评论

有IDE自动补全的插件吗,手写IDE不能自动对齐

5年前 评论
Toiu

:joy: eolinker一把梭..

4年前 评论

你们现在用的什么

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!