前面的幾篇部落格,我們已經把Fabric環境搭建好了,也可以使用Go開發ChainCode了,那麼我們在ChainCode開發完畢後,可以通過CLI來測試ChainCode的正確性,ChainCode開發後,接下來就是關於Application的編寫了。
Application分為2部分,一部分是關於後來業務邏輯的,也就是Web API,一般是通過RESTful的形式提供,另外一部分就是UI,當然大多數情況下都是GUI,也就是網站前端,Windows程式,APP之類的。關於前端,我由於沒啥藝術細胞,做出來的介面很醜,所以也就揚長避短,很少做前端開發,專注於後臺業務邏輯的實現。
一 簡介
在Web API的開發中,業內最知名的工具就是Swagger了,這簡直就是一件神器啊!我之前在C#開發的時候就使用ABP框架,用到了Swagger,在試著使用Go的Web開發框架Beego的時候也看到了Swagger,現在使用Node開發,想不到又用到Swagger,只能說明Swagger的跨平臺跨語言的能力太強了。Swagger可以幫助我們把API文件化,方便進行測試。
Swagger的開發方式有2種:
- 使用Web開發框架中遷移過來的Swagger庫,也就是先程式碼,後生成API文件的模式。比如ABP框架中就是,我們只需要在ApiController中定義好介面和註釋好,其框架就可以幫我們生成Swagger介面。
- 使用Swagger的yaml檔案定義API介面,定義好後,再使用Swagger官方提供的CodeGen生成對應語言的程式碼。
第一種開發方式要看你使用的Web框架的支援情況,接下來我們要講的就是第二種開發方式。
二 編寫Swagger YAML
官方已經給我提供一個寵物商店的示例,並提供了強大的語法檢查和預覽功能,那就是Swagger Editor,我們直接訪問http://editor.swagger.io/ 就可以看到。如果由於某些神祕的力量,造成訪問特別緩慢或者無法訪問,我們也可以下載Swagger Editor的Image到本地來執行。
直接在安裝了Docker的環境中執行如下命令:
docker pull swaggerapi/swagger-editor docker run -p 80:8080 swaggerapi/swagger-editor
然後就可以訪問http://{Your_Server_IP}。
不管是線上的Editor或者是本地部署的Docker,我們最終看到是這樣一個介面:
左邊視窗就是我們要編輯的YAML檔案的內容,右邊視窗就是預覽的API文件的效果。
關於YAML檔案,其實可讀性還是很強的,大部分都不需要解釋就知道是什麼意思,下面我來著重介紹以下幾個比較重要的元素:
1. host&basePath
host是指定了我們的API伺服器的地址,也就是我們部署了Web API時,是部署在哪個Server上。如果我們是本地開發,而且使用了自定義埠,比如8080,那麼需要改成localhost:8080。
basePath是指定API的虛擬目錄,比如我們有個獲得所有使用者列表的API是:GET /User,如果我們設定了basePath是“/api”,那麼我們要訪問的路徑應該是:
GET http://localhost:8080/api/User
當然,如果我們要更規範,比如把API版本也放進去,那麼我們可以設定basePath為”/api/v1”,於是我們的訪問路徑就是:
GET http://localhost:8080/api/v1/User
這個basePath引數涉及到伺服器端api路由的生成,而host涉及到各個API測試時候的呼叫地址。
2. tags
Tags是用於我們對大量的API進行分割槽用的,說簡單點就是為了大量的API能夠更好看,更容易查詢。我們可以為tag新增註釋,使得API文件更容易讀懂。
Tags不涉及到後臺的改變,每一個具體的API都可以指定屬於哪個(或者哪幾個tag),然後在Swagger顯示的時候,會將這些API歸到所屬的Tag下面去。
【注意:YAML檔案格式嚴格要求縮排,就像Python一樣,所以如果我們在新增元素的時候一定要注意縮排是否正確。】
比如我們新建一個Tag叫Bank,然後增加一點對這個Tag的描述,接下來我們再到/pet post下面,可以把tags增加一行,寫為銀行,然後就可以看到右邊的預覽視窗更新了,顯示了銀行這個Tag相關的API:
如果沒有重新整理,我們可以點選上面選單的Edit->Convert to YAML可以看到效果。
3. paths
這是最主要的配置元素。主要的API配置都在這個環節。下面一級一級的講解。
第一級是URL,以/開頭,URL中可以指定引數。比如我們要獲得某個bankId對應的銀行資訊,那麼URL就是
/bank/{bankId}
第二級是HTTP方法,我們在WebAPI中主要用到的方法有:查詢get,建立post,修改put和刪除delete。因為我們是要查詢某個銀行ID對應的銀行資訊,所以我們在這一級輸入get
第三級有多個元素,分別是:
tags,說明這個API是屬於哪個Tag的。
summary,對該介面的簡單描述,一句話即可。
description,顧名思義,是介面的介紹,可以寫的詳細一點。
operationId,這是對應的後臺的方法名,Swagger的路由就可以根據URL和這裡的operationId找到對應的Action方法。
consumes,是客戶端往伺服器傳的時候,支援什麼型別,一般我們只需要保留json即可,可以把xml刪除。如果是get方法,不需要該元素。
produces,就是伺服器在返回給客戶端資料的時候,是什麼樣式的資料,我們仍然保留json即可。
parameters就是具體的引數,這裡的設定比較複雜,包括指定引數是在URL中還是在Body中,傳入的引數是什麼型別的,是否必須有該引數,對該引數的描述等。如果引數是一個物件,那麼需要新增對該物件型別的引用,而物件的定義在後面definitions節點中。
responses是伺服器返回的HTTP Code有哪些。每一種狀態碼錶示什麼意思。
security是指定該介面的安全檢查方式,如果沒有設定,那麼就是匿名訪問。其引用的是securityDefinitions中的定義。
x-swagger-router-controller,這是一個擴充套件元素,用來指定該URL對應的後臺的Controller名。
結合上面介紹的,我們自定義一個根據ID獲取Bank物件的YAML內容如下:
/bank/{bankId} : get: tags: - Bank summary: 根據銀行ID獲得銀行基本資訊 description: 詳細描述 operationId: getBankById produces: - application/json parameters: - name: bankId in: path description: 銀行物件的主鍵ID required: true type: integer format: int64 responses: '200': description: 找到銀行 schema: $ref: '#/definitions/Bank' '400': description: 無效的ID '404': description: ID對應的銀行未找到
4. securityDefinitions
這是安全定義模組,在這裡可以定義我們WebAPI的安全認證方式,比如:
- Basic Authentication
- API Keys
- Bearer Authentication
- OAuth 2.0
- OpenID Connect Discovery
- Cookie Authentication
這裡面這麼多種認證方式,很多我也沒用過,瞭解不深,我主要用的是Bearer和OAuth 2.0,具體設定大家可以參考文件:
https://swagger.io/docs/specification/authentication/
5. definitions
這裡是定義我們在API中會涉及到哪些JSON物件的地方。也就是說我們在API中要POST上去的JSON或者通過GET由伺服器返回的JSON,其物件都在這裡定義,上面的步驟直接引用這裡的定義即可。
比如我們上面需要引用到Bank物件,那麼我們在這裡定義如下:
Bank: type: object properties: id: type: integer format: int32 name: type: string
如果是物件巢狀引用了其他物件,也可以通過$ref的方式引用過去,我們可以參考官方示例中的Pet物件,就引用了Category。
以上各個元素我只是簡單的講解,對於各種深入的用法,大家可以參考官方文件:https://swagger.io/docs/
三 生成後臺程式碼
只要我們預覽右邊的程式碼沒有報任何錯誤,那麼我們就可以生成對於的後臺程式碼了。這裡因為Fabric SDK是Node的,所以我們的Web API也是使用Node來開發。我們點選Generate Server選單下的nodejs-server選項:
系統會下載一個壓縮包,該壓縮包解壓後就是我們的Web API Node專案。在安裝了Node的機器上,我們使用以下命令,安裝專案所依賴的包:
npm install --registry=https://registry.npm.taobao.org
安裝完畢後,執行以下命令:
npm start
我們可以看到網站地址是:http://localhost:8080/docs
開啟瀏覽器,訪問這個網站,就可以看到Swagger生成的UI,並看到我們自定義的獲取銀行物件的方法。
下面,我們來試一試傳入引數1,並呼叫該API,可以看到這樣的結果:
這裡返回的是Swagger給我們Mock的一個假結果,如果我們要返回真實的結果,那麼需要在Controllers資料夾中找到BankService.js,看到如下的內容:
'use strict'; exports.getBankById = function(args, res, next) { /** * 根據銀行ID獲得銀行基本資訊 * 詳細描述 * * bankId Integer 銀行物件的主鍵ID * returns Bank **/ var examples = {}; examples['application/json'] = { "name" : "aeiou", "id" : 0 }; if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); } else { res.end(); } }
將Mock程式碼部分刪除,將我們真實的業務邏輯寫進去即可完成我們的WebAPI的開發工作。
四 總結
Swagger真的不愧是Web API開發的神器,太好用了。另外官方還有SwaggerHub,支援多人協作編寫YAML文件,不過是收費的。我們在專案中其實可以通過Git來管理yaml檔案,因為該檔案存在於WebAPI專案的api資料夾中,所以其實大家可以共同編輯,然後使用Git來合併衝突。另外Swagger還有Client,看了一些支援各種語言,各種框架,各種APP開發,真是太強大了,我由於不開發GUI,所以沒怎麼接觸,需要你去研究了。