Swagger 是我目前用過(guò)的最優(yōu)秀的 Api Doc 協(xié)議沒(méi)有之一呐芥。它與其他 Api Doc 協(xié)議(如apidocjs)最大的差別在于缘缚,Swagger 不僅僅可以定義 Api 的 Route / Request Param 和 Response聋丝,還可以定義 Definitions Object / Security Definitions Object 以及 Reference Object蒲犬。
以一個(gè)電商項(xiàng)目為例陨收,系統(tǒng)里有 商品(Product)和 訂單(Order)兩個(gè) Model肛搬,其中 Order 有一個(gè) product_id
字段用于關(guān)聯(lián)對(duì)應(yīng)的商品没佑;有兩個(gè)接口,一個(gè)是獲取商品詳情 /product/{product}
温赔,另一個(gè)是獲取訂單詳情 /order/{order}
蛤奢,為了減少Api請(qǐng)求數(shù)量,在獲取訂單詳情時(shí)我們希望同時(shí)返回對(duì)應(yīng)的商品數(shù)據(jù)陶贼。
如果我們用 apidocjs 來(lái)寫(xiě)的話啤贩,會(huì)是類似下面的注釋
/**
* @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 的字段在兩個(gè)接口的注釋里各寫(xiě)了一遍,這就很繁瑣拜秧;另外一個(gè)更嚴(yán)重的問(wèn)題是瓜晤,如果未來(lái) Product 表的字段發(fā)生了增減,我們需要去修改每一個(gè)會(huì)輸出 Product 的接口的注釋腹纳,更繁瑣而且容易遺漏痢掠。
所以我們需要有一個(gè)可以定義 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 字段時(shí)足画,我們使用了 $ref
雄驹,也就是 Reference Object,這就是告訴 Swagger淹辞,Order 的product 字段指向了 Product 的定義医舆。
再來(lái)看看 Route / Request Param 和 Response 在Swagger 中怎么寫(xiě):
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'
通過(guò) $ref
完美解決了增減字段需要修改多處的問(wèn)題。
我在第一次使用 Swagger 的時(shí)候象缀,雖然被其強(qiáng)大的定義功能所折服蔬将,卻又對(duì)寫(xiě) Swagger 文檔極其的厭惡,因?yàn)楣俜教峁┑?Swagger Editor 速度不僅慢央星,還時(shí)不時(shí)出錯(cuò)霞怀,明明寫(xiě)對(duì)了文檔格式非要告訴我有問(wèn)題,只能刷新頁(yè)面重新加載莉给。
直到最近發(fā)現(xiàn)了一個(gè)項(xiàng)目 swagger-php毙石,通過(guò)注釋的方式來(lái)生成 JSON 格式的 Swagger 文檔,只需要通過(guò) \Swagger\scan()
函數(shù)掃描一個(gè)目錄下所有 PHP 文件的注釋 (可以創(chuàng)建一個(gè)完全只有注釋的 php 文件來(lái)放一些與 request / response 并無(wú)直接關(guān)聯(lián)的定義颓遏,比如 Security Definitions Object)徐矩。
有了 JSON 格式的文檔之后,配合 Swagger UI 就可以展示出非常美觀的 Api 文檔了叁幢,可以看這個(gè) Demo滤灯,還支持在文檔頁(yè)面直接發(fā)起 Api 請(qǐng)求,大大的方便曼玩!