在PHPer
中,不少人據說過Swagger
,部分人知道Swagger
是用來作API文檔的,然而只有少數人真正知道怎麼正確使用Swagger
,由於PHP
界和Swagger
相關的資料實在是太少了。因此鄙人斗膽一試,但願能以本文幫助到你們瞭解Swagger
,今後告別整天用Word
、Markdown
折騰API文檔的日子。javascript
Swagger is a simple yet powerful representation of your RESTful API. With the largest ecosystem of API tooling on the planet, thousands of developers are supporting Swagger in almost every modern programming language and deployment environment. With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability.php
Swagger是一種簡單、強大的RESTful API表現形式。
其擁有地球上最大的API工具生態環境,無數程序員在幾乎全部主流語言和開發環境中添加了對Swagger的支持。
只要你的API添加對Swagger的支持,你就等於擁有了可交互的API文檔,SDK代碼生成以及外部使用友好的API。html
- Swagger.io首頁
寫了這麼一堆貌似很屌的話,因此……Swagger
究竟是個啥?是一套代碼仍是一個軟件呢?前端
其實和官網高度歸納的描述同樣,Swagger
是一種通用的、和編程語言無關的API的描述規範。只要開發者在本身的API之上添加符合Swagger
規範的描述,就能利用上Swagger
豐富的生態,找到符合本身開發語言的工具去作不少事:好比最經常使用的生成API文檔,或者生成返回假數據的服務端基礎代碼等等。java
人類的文字即是一種規範,人理解了文字的規範就能夠進行閱讀,機器按照規範也能夠進行文字識別,武林祕籍能夠寫成文字讓全部人練習,人的思想也能夠寫成文字進行傳播。人類的不少經典書籍都被翻譯成了多國文字,Swagger
的描述一樣也支持用YAML
、XML
或JSON
來表示,含義都是一致的。Swagger UI
經過任意一種形式的Swagger
描述信息就能渲染出酷炫的API文檔,服務端接口代碼生成工具也能經過這個描述信息生成Controller
代碼,圍繞着Swagger
,一個強大的API生態環境就出現了。git
那麼就是說,之前我用Markdown
寫文檔,如今我用YAML/XML/JSON
寫文檔就好了?程序員
是的,但Swagger
功能不止如此。使用Swagger
能夠分爲兩種狀況:github
項目未開始,須要先定義好API使前端和後端可以同時開發;編程
API已完成,須要提供文檔;json
第二種狀況,咱們確實能夠直接開始編寫一個JSON
或者YAML
文件來描述現有的API(使用Swagger-Editor),不過這裏咱們主要介紹第一種狀況,全方位感覺Swagger
。
繼續以前,咱們先介紹一下另外一個東西(也許這麼多新概念就是把你們弄暈了的緣由……找到Swaager
的應用最佳實踐須要一點點時間,請繼續看)。
Annotation
是Java
引入的一個概念,簡單來講就是用來給對應的源代碼添加額外的元數據(關於數據的更詳細的數據)的一種語法。Annotation
自己不影響代碼的執行,只能經過額外的工具解析或執行,一般用來提供代碼檢查、數據類型標註等功能。因爲Annotation
的強大,不少編程語言都引入了這個概念,包括PHP
。
那麼,若是咱們能將Swagger
的描述用Annotation
的方式直接寫在Controller
上,豈不是既方便又好維護?
在PHP
中使用Swagger
,咱們須要一個工具去編寫和解析Annotation
到Swagger
的描述(例如JSON
形式),Swagger
豐富的生態不是吹的,這裏咱們直接使用前人寫好的swagger-php。而編寫API
咱們則使用Laravel
框架(5.1
)。固然,swagger-php
自己和用哪一種框架開發是不要緊的。
首先在Laravel
項目中安裝swagger-php
:
$ composer require zircote/swagger-php
接着定義一個Controller
用來測試:
$ artisan make:controller SwaggerController --plain
在Controller
中加上兩個方法:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; class SwaggerController extends Controller { /** * 返回JSON格式的Swagger定義 */ public function getJSON() { } /** * 假設是項目中的一個API */ public function getMyData() { } }
相應的,咱們增長路由配置:
<?php Route::group(['prefix' => 'swagger'], function () { Route::get('json', 'SwaggerController@getJSON'); Route::get('my-data', 'SwaggerController@getMyData'); });
咱們先實現getJSON
方法,使其可以返回合法的Swagger
定義:
<?php // ... /** * 返回JSON格式的Swagger定義 * * 這裏須要一個主`Swagger`定義: * @SWG\Swagger( * @SWG\Info( * title="個人`Swagger`API文檔", * version="1.0.0" * ) * ) */ public function getJSON() { // 你能夠將API的`Swagger Annotation`寫在實現API的代碼旁,從而方便維護, // `swagger-php`會掃描你定義的目錄,自動合併全部定義。這裏咱們直接用`Controller/` // 文件夾。 $swagger = \Swagger\scan(app_path('Http/Controllers/')); return response()->json($swagger, 200); } // ...
訪問一下/swagger/json
,若是咱們看到下面的返回就說明搭建成功了:
{"swagger":"2.0","info":{"title":"\u6211\u7684`Swagger`API\u6587\u6863","version":"1.0.0"},"paths":{},"definitions":{}}
而後咱們來定義項目中的API接口:
<?php // ... /** * 假設是項目中的一個API * * @SWG\Get(path="/swagger/my-data", * tags={"project"}, * summary="拿一些神祕的數據", * description="請求該接口須要先登陸。", * operationId="getMyData", * produces={"application/json"}, * @SWG\Parameter( * in="formData", * name="reason", * type="string", * description="拿數據的理由", * required=true, * ), * @SWG\Response(response="default", description="操做成功") * ) */ public function getMyData() { //todo 待實現 } // ...
雖然API尚未真正實現,可是咱們的第一個API文檔已經完成了(後面咱們在講每一個Annotation
的含義)!來看看如今JSON
接口的輸出內容:
{"swagger":"2.0","info":{"title":"\u6211\u7684`Swagger`API\u6587\u6863","version":"1.0.0"},"paths":{"\/swagger\/my-data":{"get":{"tags":["project"],"summary":"\u62ff\u4e00\u4e9b\u795e\u79d8\u7684\u6570\u636e","description":"\u8bf7\u6c42\u8be5\u63a5\u53e3\u9700\u8981\u5148\u767b\u5f55\u3002","operationId":"getMyData","produces":["application\/xml","application\/json"],"parameters":[{"name":"reason","in":"formData","description":"\u62ff\u6570\u636e\u7684\u7406\u7531","required":true,"type":"string"}],"responses":{"default":{"description":"\u64cd\u4f5c\u6210\u529f"}}}}},"definitions":{}}
固然,若是直接把這個甩給前端同窗,他們必定會一臉懵逼看着你的……爲了把JSON
定義轉化爲能夠閱讀和交互的API,咱們還須要用到Swagger-UI
。Swagger-UI
是一套不依賴後端的純HTML
程序,只須要將以前輸出JSON
的接口地址給它,就能獲得一個強大的API文檔了。爲了不請求跨域問題,咱們將Swagger-UI
部署在項目的public/swagger-ui/
文件夾中。安裝很是簡單,直接在GitHub
上下載壓縮包,解壓縮以後將dist/
文件夾下的全部內容放到public/swagger-ui/
就好了。
在訪問以前,咱們先改一下Swagger-UI
默認請求的接口地址,打開public/swagger-ui/index.html
,找到如下代碼:
<script type="text/javascript"> $(function () { var url = window.location.search.match(/url=([^&]+)/); if (url && url.length > 1) { url = decodeURIComponent(url[1]); } else { url = "http://petstore.swagger.io/v2/swagger.json"; // 就是這一行 } // ...
將url
改爲咱們本身接口的地址,例如http://my.project/swagger/json
。打開瀏覽器,訪問/swagger-ui/
,就能看到API文檔了:
在這個高大上的API文檔上稍微玩一下子,你可能冒出幾個問題:
有沒有中文支持?
每次都要點一次才能展開API列表好麻煩,能默認展開嗎?
右下角那個ERROR
是什麼意思?
可能你還有更多問題,但咱們先說這三個吧…
Swagger-UI
支持多國語言,仍是打開swagger-ui/index.html
,大約在30行左右:
// ... <!-- Some basic translations --> <!--<script src='lang/translator.js' type='text/javascript'></script>--> <!--<script src='lang/ru.js' type='text/javascript'></script>--> <!-- <script src='lang/en.js' type='text/javascript'></script> --> // ...
咱們改成:
// ... <!-- Some basic translations --> <script src='lang/translator.js' type='text/javascript'></script> <script src='lang/zh-cn.js' type='text/javascript'></script> // ...
這樣就會變成中文了:
大概在swagger-ui/index.html
的74行左右有如下代碼:
// ... onFailure: function(data) { log("Unable to Load SwaggerUI"); }, docExpansion: "none", // 這一行就是用來設置文檔默認展開層級的 jsonEditor: false, // ...
這個配置有三個值:
none
摺疊全部內容
list
展開全部分組的API列表
full
展開全部分組的API列表以及每一個API的請求細節
通常來講設置爲list
就能夠了。
Swagger-UI
默認會將你的接口JSON
傳給swagger.io
進行格式驗證,而後對於咱們已經使用了swagger-php
的項目來講基本不須要(由於寫錯了Annotation
的話會形成Swagger JSON
接口報錯),並且內部項目有時也不方便暴露,因此咱們能夠關閉驗證功能來去除右下角的ERROR
提示圖標。這個配置並不存在於swagger-ui/index.html
中,咱們須要手動在Swagger UI
聲明時設置一個新參數:
// ... window.swaggerUi = new SwaggerUi({ // ... validatorUrl: null, //添加這個配置 }); // ...
再次刷新以後驗證提示就完全消失了。
若是你須要這個驗證提示,但又不想使用swagger.io
的公用服務,你也能夠本身搭建一個,點這裏查看Swagger Validator Badge
的使用方法。
Swagger UI
自己提供了不少配置和參數供用戶自定義,點這裏查看,你們能夠隨意發揮。
下次再寫關於swagger-php
的使用細節。