摘要:需求和背景需求為客戶端同事寫接口文檔的各位后端同學已經在各種場合回憶了使用自動化文檔工具前手寫文檔的血淚史我的故事卻又不同因為首先來說我在公司是組負責人屬于上述血淚史中催死人不償命的客戶端陣營但血淚史卻是相通的沒有自動化文檔的日子對接口就是
需求和背景
需求:
為客戶端同事寫接口文檔的各位后端同學,已經在各種場合回憶了使用自動化文檔工具前手寫文檔的血淚史.
我的故事卻又不同,因為首先來說,我在公司是 Android 組負責人,屬于上述血淚史中催死人不償命的客戶端陣營.
但血淚史卻是相通的,沒有自動化文檔的日子,對接口就是開發流程中最低效的環節.
因此決定使用 swagger 搭建由php注釋生成文檔的流程.
背景:
我們的 restful api 項目采用 phalcon 框架,整體結構很簡單,我們只需要用 swagger 掃描 controller 目錄即可.
下簡稱我們的 php api 項目為 php_api_project.
服務器采用 nginx.
先說下最終的文檔生成流程會是什么樣子,以便先有個整體的認識:
搭建完成后, 整個流程, 從文檔生成到前端展現, 大體如下:
在php文件中寫 swagger 格式的 /* 注釋 /
用 swagger-php 內的 bin/swagger.phar 命令掃描 php controller 所在目錄, 生成 swagger.json 文件
將 swagger.json 文件拷貝到 swagger-ui 中 index.html 指定的目錄中
打開 swagger-ui 所在的 url, 就可以看到文檔了. 文檔中的各個 api 可以在該網址上直接訪問得到數據.
實現此需求只需要 swagger 的如下兩個項目:
swagger-php: 掃描 php 注釋的工具. 內含一個不錯的例子.
swagger-ui: 用以將掃描工具生成的 swagger.json 文件內容展示在網頁上.
首先將這兩個項目下載到本地:
$ git clone https://github.com/swagger-api/swagger-ui.git $ git clone https://github.com/zircote/swagger-php.git文檔生成工具部署
說是部署,主要就是產生 bin/swagger 這個用來生成 swagger.json 文件的命令.
主要工作,就是用 composer 解決下依賴就可以了.
因為國內直接用 composer 比較蛋疼,所以最好設置下國內的那個 composer 源.
這樣的話, 整個 文檔生成工具的部署 就是下面三行命令:
$ cd swagger-php $ composer config repo.packagist composer https://packagist.phpcomposer.com $ composer update
只要中間不報錯,就算部署完成了. 完成后可以生成一份文檔試一下.
swagger-php 項目下的 Examples 目錄下有一個示例php工程,里面已經用 swagger 格式寫了各種接口注釋, 我們來嘗試生成一份文檔.
執行下面命令:
$ cd swagger-php $ mkdir json_docs $ php ./bin/swagger ./Examples -o json_docs/
上面命令會掃描 Examples 目錄中的php文件注釋, 然后在 json_docs 目錄下生成 swagger.json 文件.
這個 swagger.json 文件就是前端 swagger-ui 用來展示的我們的api文檔文件.
NOTE: swagger-php 只是個工具,放在哪里都可以.
前端 swagger-ui 部署:部署方法很簡單,就三步:
1. 將 swagger-ui 項目中的 dist 文件夾拷貝到 php_rest_api 根目錄下.NOTE1: 只需要拷貝dist這一個文件夾就可以了.最好重命名下,簡單起見,這里不再重命名.
NOTE2: 我們的項目根目錄和 nginx 配置的 root 是同一個目錄.其實不用放跟目錄,只要放到一個不用跨域就跨域訪問的目錄就可以了. 為啥有跨域問題? 后面會講.
只改一行就可以.
簡單起見,這里直接將 swagger.json 目錄指定在 dist 目錄下即可. 我們這里屢一下預設條件:
假設 php_api_project 項目的 host 是 api.my_project.com;
假設 php_api_project 項目在 nginx 中指定的 root 即為其根目錄;
假設 swagger-ui 里的 dist 文件夾放在上述根目錄中;
假設 swagger.json 文件就打算放在上述 dist 目錄下 (php_api_project/dist/swagger.json) ;
那么 index.html 中把下面的片段改成這樣:
var url = window.location.search.match(/url=([^&]+)/); if (url && url.length > 1) { url = decodeURIComponent(url[1]); } else { url = "http://api.my_project.com/dist/swagger.json"; }3. 拷貝 swagger.json 到上述目錄中.
# 把 swagger-php_dir 這個,換成你的 swagger-php 錄即可 cp swagger-php_dir/json_docs/swagger.json php_api_project/dist/
上述步驟完成后, 訪問 http://api.my_project.com/dis... 就可以看到 Examples 那個小項目的 api 文檔了.
編寫 PHP 注釋swagger-php 項目的 Example 中已經有了很多相關例子,照著復制粘貼就可以了.
更具體的相關注釋規則的文檔,看這里:
http://bfanger.nl/swagger-exp...
假設我的項目 controller 所在目錄為 php_api_project/controller/, 那么我只需要掃描這個目錄就可以了,不用掃描整個 php 工程.
為了在 swagger.json 中生成某些統一的配置, 建立 php_api_project/controller/swagger 目錄. 目錄存放一個沒有代碼的php文件,里面只寫注釋.
我給這個文件取名叫 Swagger.php, 大體內容如下:
以后大家就在這里愉快的對接口把!
以后大家就在這里愉快的對接口把!
以后大家就在這里愉快的對接口把!
" * ), * * @SWGTag( * name="User", * description="用戶操作", * ), * * @SWGTag( * name="MainPage", * description="首頁模塊", * ), * * @SWGTag( * name="News", * description="新聞資訊", * ), * * @SWGTag( * name="Misc", * description="其他接口", * ), * ) */
如上所示,我的這個php文件一行php代碼也沒有,就只有注釋,為了定義一些全局的swagger設置:
schemes: 使用協議 (可以填多種協議)
host: 項目地址, 這個地址會作為每個接口的 url base ,拼接起來一期作為訪問地址
consumes: 接口默認接收的MIME類型, 我的例子中的 formData 對應post表單類型. 注意這是項目默認值,在單個接口注釋里可以復寫這個值.
produces: 接口默認的回復MIME類型. api接口用的比較多的就是 application/json 和 application/xml.
@SWGInfo: 這個里面填寫的東西,會放在文檔的最開頭,用作文檔說明.
@SWGTag: tag是用來給文檔分類的,name字段必須唯一.某個接口可以指定多個tag,那它就會出現在多組分類中. tag也可以不用在這里預先定義就可以使用,但那樣就沒有描述了. 多說無益,稍微用用就啥都明白了.
然后就是給每個接口編寫 swagger 格式的注釋了.還是舉個栗子吧:
/** * @SWGPost(path="/user/login", tags={"User"}, * summary="登錄接口(用戶名+密碼)", * description="用戶登錄接口,賬號可為 用戶名 或 手機號. 參考(這個會在頁面產生一個可跳轉的鏈接: [用戶登錄注意事項](http://blog.csdn.net/liuxu0703/)", * @SWGParameter(name="userName", type="string", required=true, in="formData", * description="登錄用戶名/手機號" * ), * @SWGParameter(name="password", type="string", required=true, in="formData", * description="登錄密碼" * ), * @SWGParameter(name="image_list", type="string", required=true, in="formData", * @SWGSchema(type="array", @SWGItems(ref="#/definitions/Image")), * description="用戶相冊. 好吧,沒人會在登錄時要求填一堆圖片信息.這里是為了示例 帶結構的數據, @SWGSchema ,這個結構需要另行定義,下面會講." * ), * @SWGParameter(name="video", type="string", required=true, in="formData", * @SWGSchema(ref="#/definitions/Video"), * description="用戶 呃... 視頻? 同上,為了示例 @SWGSchema ." * ), * @SWGParameter(name="client_type", type="integer", required=false, in="formData", * description="調用此接口的客戶端類型: 1-Android, 2-IOS. 非必填,所以 required 寫了 false" * ), * @SWGParameter(name="gender", type="integer", required=false, in="formData", * default="1", * description="性別: 1-男; 2-女. 注意這個參數的default上寫的不是參數默認值,而是默認會被填寫在swagger頁面上的值,為的是方便用swagger就地訪問該接口." * ), * ) */ public function loginAction() { // php code } /** * @SWGGet(path="/User/myWebPage", tags={"User"}, * produces={"text/html"}, * summary="用戶的個人網頁", * description="這不是個api接口,這個返回一個頁面,所以 produces 寫了 text/html", * @SWGParameter(name="userId", type="integer", required=true, in="query"), * @SWGParameter(name="userToken", type="string", required=true, in="query", * description="用戶令牌", * ), * ) */ public function myWebPageAction(){ // php code }
規則簡單明了,看著代碼大家就都懂了.不懂的話,去看文檔吧...
上面 login 接口中用到了兩個有結構的數據, 一個是 image 類型的數組, 一個是 video 類型的結構.
(其實結構化的參數只能在 in="body" 時才可以用,但這并不妨礙我們為了簡化問題,把結構化數據格式化為 json 當字符串傳遞. 我們只要將這種結構展現在文檔里就可以了)
這種有結構的東西 swagger 也可以用 php 注釋定義:
這樣當這兩個類也被 swagger-php/bin/swagger 掃描到后,其他地方就可以正確引用到 Image 和 Video 為名字的這兩個結構體了.
這樣做的好處是,在接口參數文檔中,這個結構會被展示出來,這樣客戶端同學就知道該傳什么結構了.
我的接口栗子里都沒有寫 response 規則,是因為我們用 json 作為返回載體,返回錯誤碼也是包含在這個 json 結構體里. 并且多數接口返回的json格式都很復雜,用 swagger 的 response 規則基本沒法描述.
swagger 的 response 編寫規則是按照 http 的 response code 來的 (404, 401 等), 總之對我們的接口來說,這套描述規則不好用.
因此我就直接舍棄了 response 描述, 直接用 swagger 就地請求接口看看返回了什么就是. 再不行就把接口的返回信息在 description 里大體描述一下.
文檔寫完后,就可以調用 swagger-php/bin/swagger 命令生成 swagger.json, 再拷貝到 swagger-ui 中你指定的那個目錄中,就可以訪問文檔了.
NOTE:
大家應該已經看出來了,其實接口的注釋不一定要寫在接口上,憑空寫注釋,一樣能生成文檔.所以不必糾結各個注釋放在什么地方. 比如 swagger 整體定義, tag 定義等,寫在任意可以被掃描到的 php 文件中就可以了.
常用字段簡要說明這里只是自己理解加翻譯的簡要說明,更詳細的字段說明,還是要去看文檔.再次貼出文檔:
http://bfanger.nl/swagger-exp...接口描述 (@SWGGet, @SWGPost 等) 常用字段:
summary - string 接口的簡要介紹,會顯示在接口標頭上,不能超過120個字符 description - string 接口的詳細介紹 externalDocs - string 外部文檔鏈接 operationId - string 全局唯一的接口標識 consumes - [string] 接口接收的MIME類型 produces - [string] 接口返回的MIME類型,如 application/json schemes - [string] 接口所支持的協議,取值僅限: "http", "https", "ws", "wss" parameters - [Parameter Object | Reference Object] 參數列表參數描述 (@SWGParameter) 常用字段:
name - string 參數名. 通過路徑傳參(in 取值 "path")時有注意事項,沒用到,懶得看了... in - string 參數從何處來. 必填. 取值僅限: "query", "header", "path", "formData", "body" description - string 參數描述. 最好別太長 type - string 參數類型. 取值僅限: "string", "number", "integer", "boolean", "array", "file" required - boolean 參數是否必須. 通過路徑傳參(in 取值 "path")時必須為 true. default - * 默認值. 在你打算把參數通過 path 傳遞時規矩挺多,我沒用到.用到的同學自己看文檔吧.自動生成文檔此段寫于 2018-04-27. 本文其他段落成于 2017-01-12. 方法僅限 git 項目.
今天有朋友問 php swagger 的使用方法, 又審了一遍此文, 才發現沒有寫自動生成這部分.
每次更新項目還要手動生成文檔的話, 就太麻煩了. 這種操作豈能不自動化. 方法如下:前提: 項目為 git 項目. 項目部署以 git 為基礎.
原理: 使用 git 的 hook 機制 在適當節點執行文檔生成命令.
時機: 有兩種: 如果使用 git 部署項目, 則可以在部署時自動生成; 如果不是, 也可以考慮在 git commit 時自動生成.
步驟:首先找到需要被掃描 controller 所在目錄, 假設其為 /project_path/app/controllers/.
然后找到 swagger 生成的 json 格式文檔應該放置的地方, 假設其為 /project_path/swagger/docs/.
那么生成文檔的命令如下:php /path/to/swagger-php/bin/swagger /project_path/app/controllers/ -o /project_path/swagger/docs/那么直接把上面這句命令放在對應的項目中的 .git/hooks/post-update 腳本中即可, 如沒有則新建.
好吧, 上面那行命令是為了一眼可以看出這行命令是做什么的. 但它有個壞處, 就是要把項目的絕對路徑寫死在腳本里, 這樣這個腳本就不具有通用性. 上面這行命令可以更新為下面的這行等價命令:
proj_root=$(readlink -f $(dirname $(git rev-parse --git-dir))) && php /path/to/swagger-php/swagger-php/bin/swagger $proj_root/app/controllers/ -o $proj_root/swagger/docs/如此, 則每次該項目代碼執行 git pull 命令時, swagger 文檔將會自動更新.
遇到的問題 跨域問題:swagger 牛X的地方就是它可以在文檔上就地訪問接口并展示輸出,對于調試和對接口非常的方便.但如果不想將 swagger-ui 部署在接口項目下,那么在 swagger-ui 就地訪問接口時,就會因跨域問題而請求不到結果. (Response Headers: no response from server; Response Body: no content).
登錄鑒權:
這里不講跨域問題怎么解決,只是給遇到上面的問題的各位一個思路,知道錯誤是由跨域產生的,就好解決了.如果要將文檔放在公網,直接暴露自己的接口可不太合適. 因此要給文檔的訪問地址做鑒權.
1. 首先用 htpasswd 命令,為需要訪問文檔的同學生成帳號名和密碼:
因為安全性要求不高,并且公司較小開發組人員不多,我就直接用了 nginx 提供的 http basic auth 做了登錄鑒權.
老規矩,先貼官方文檔:
https://www.nginx.com/resourc...
這樣做鑒權很簡單,分分鐘搞定. 不詳述, 就兩步:$ htpasswd -cb your/path/to/api_project_accounts.db admin password_for_admin $ htpasswd -b your/path/to/api_project_accounts.db liuxu 123456 $ htpasswd your/path/to/api_project_accounts.db xiaoming-c 選項表示如果賬號文件 ( api_project_accounts.db ) 不存在,則新建之. 因此創建第一個賬號時一定要加 -c, 之后創建則一定不要再加 -c.
2. 然后在 nginx 的項目配置中給自己的這個訪問地址開啟 http basic auth 就可以了.
-b 參數表示明文指定密碼,就是上面第一條和第二條命令中最后一個輸入 (password_for_admin, 123456) . 因此如果不想明文指定,可以不加 -b, 像上面的第三條命令,就會和sudo命令一樣,讓你輸入一段看不見的密碼.
上面命令創建了三個賬號, admin, liuxu, xiaoming, 并將賬號密碼保存在 api_project_accounts.db 文件中.location /dist { auth_basic "my api project login"; auth_basic_user_file your/path/to/api_project_accounts.db; }記得改完了重啟 nginx:
nginx -s reload這樣一個簡單的登錄鑒權就建立起來了.
NOTE:
如果系統里沒有 htpass 這個命令, 可以安裝 apache 的 httpd 服務器軟件, htpass 這個命令就包含在其中:
yum install httpd參考:[1] swagger 官網
[2] swagger 項目地址
[3] swagger ui 項目地址
[4] swagger php 項目地址
[5] swagger 文檔參考地址
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28577.html
摘要:集成生成接口文檔原文簡介由于的特性,用來開發變得非常容易,并且結合來自動生成文檔變得方便快捷。使用生成,我們可以得到交互式文檔。聽過與的結合,生成更加完備的文檔。接下來將基于與搭建完整的文檔系統。 Spring Boot Swagger2 集成REST ful API 生成接口文檔 原文 簡介 由于Spring Boot 的特性,用來開發 REST ful 變得非常容易,并且結合 Sw...
摘要:使用生成,我們可以得到交互式文檔,自動生成代碼的以及的發現特性等。方法指定掃描的包會生成文檔默認是顯示所有接口可以用注解標識該接口不顯示。 程序員都很希望別人能寫技術文檔,自己卻很不愿意寫文檔。因為接口數量繁多,并且充滿業務細節,寫文檔需要花大量的時間去處理格式排版,代碼修改后還需要同步修改文檔,經常因為項目時間緊等原因導致文檔滯后于代碼,接口調用方的抱怨聲不絕于耳。而程序員是最擅長偷...
摘要:今天給你們帶來集成的教程。接口返回結果不明確。這些痛點在前后端分離的大型項目上顯得尤為煩躁。接口返回結果非常明確,包括數據類型,狀態碼,錯誤信息等。生成后的文件依賴如下這里使用的是的版本。另外,關注之后在發送可領取免費學習資料。 微信公眾號:一個優秀的廢人如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 快過年了,不知道你們啥時候放年假,忙不忙。反正我是挺閑的,所以有時間寫 b...
閱讀 2571·2021-09-26 10:13
閱讀 5969·2021-09-08 10:46
閱讀 685·2019-08-30 15:53
閱讀 2957·2019-08-29 16:13
閱讀 2750·2019-08-26 12:23
閱讀 3478·2019-08-26 11:24
閱讀 1085·2019-08-23 18:09
閱讀 1028·2019-08-23 17:08