天天看點

淺析如何在Nancy中使用Swagger生成API文檔

淺析如何在Nancy中使用Swagger生成API文檔

介紹了如何在Nancy中使用Swagger生成一份API文檔,并且處理在安全驗證方面遇到的問題。

上一篇部落格介紹了使用Nancy架構内部的方法來建立了一個簡單到不能再簡單的Document。但是還有許許多多的不足。

為了能稍微完善一下這個Document,這篇引用了目前流行的Swagger,以及另一個開源的Nancy.Swagger項目來完成今天的任務!

注:Swagger是已經相對成熟的了,但Nancy(2.0.0-clinteastwood)和Nancy.Swagger(2.2.6-alpha)是基于目前的最新版本,但目前的都是沒有釋出正式版,是以後續API可能會有些許變化。

下面先來簡單看看什麼是Swagger

<code>The World's Most Popular Framework for APIs.</code>這是Swagger官方的描述。能說出是世界上最流行的,也是要有一定資本的!

光看這個描述就知道Swagger不會差!畢竟人家敢這樣說。當然個人也認為Swagger确實很不錯。

通過官方文檔,我們都知道要想生成Swagger文檔,可以使用YAML或JSON兩種方式來書寫,由于我們平常寫程式用的比較多的是JSON!

是以本文主要是使用了JSON,順帶說一下YAML的文法也是屬于易懂易學的。

既然是用JSON書寫,那麼要怎麼寫呢?這個其實是有一套規定、限制,我們隻要遵守這些來寫就可以了。詳細内容可以參見OpenAPI Specification

本文後面的内容将預設園友們對Swagger有過了解。

Swagger主要有下面幾個東西,要引用基本的樣式和腳本就不在多說了。

當然,引用樣式和腳本隻是最基本的前提,下面這段js(來自swagger-ui項目)才是最為主要的!

就是在上面加上注釋的兩個屬性:url指定了我們要展示資料(JSON格式)的來源,dom_id指定了在id為<code>swagger-ui</code>的容器中展示我們的文檔。

在加載的時候建立了Swagger相關的内容,主要的有下面的兩個,其餘的用預設的就可以了。

簡單來說,我們請求了這個url拿到了這些json資料,再根據這些資料在dom_id中構造出我們所看到的頁面。有那麼點資料驅動的意思。

當然這些JSON資料是有格式要求的。可以看看下面的簡單示例

這也就意味着我們隻需要嚴格按照Swagger的定義,就可以生成一個即美觀,又可執行的API文檔了。

更多相關JSON示例可參見

https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v2.0/json

<code>Nancy.Swagger</code>是我們今天的主角,是一個基于MIT協定的開源項目。Github位址:Nancy.Swagger

當然通過上面關于Swagger的說明,也已經大概明白了這個項目主要為我們做了什麼。就是構造Swgger所需要的JSON格式的資料!

它并沒有像Swashbuckle.AspNetCore一樣內建了SwaggerUI的内容到項目中去,隻是一個提供資料的項目。

其官方的示例Demo是用跳轉到petstore.swagger.io方式來完成的。但是經常性是要等待很長時間的,應該是網絡的問題。

為了避免這一情況,可以通過下面的操作避免:

手動下載下傳swagger-ui相關的内容并添加到我們的新項目中。同時我還将這些設定成嵌入式的資源。

淺析如何在Nancy中使用Swagger生成API文檔

添加一個用于顯示的頁面,示例為doc.html,内容可以照搬swagger-ui目錄下面的index.html

在Bootstrapper中添加靜态資源的引用

在通路我們API時,将其重定向到doc.html頁面

修改doc.html的内容,将上述的url,替換成<code>@Model</code>

完成上面的内容後,就開始構造我們的文檔了。

這裡主要是設定這個API文檔的概要資訊,比如文檔的标題,此api的版本等

需要通過SwaggerMetadataProvider的SetInfo方法來設定這些資訊

下面是具體的示例代碼,寫在Bootstrapper中:

此時對應的大緻效果(這個時候是不能正常運作的,隻是顯示了這部分的效果)如下:

淺析如何在Nancy中使用Swagger生成API文檔

上面代碼生成的JSON資料是符合規範的,如下所示:

淺析如何在Nancy中使用Swagger生成API文檔

下面要做的就是構造路由相關的資訊

先在Module中定義一個簡單的路由,這個路由不帶任何參數。

然後在MetadataModule中添加相應的描述,這裡的MetadataModule與上一篇是相似的,這也是為什麼我會在上一篇先介紹不使用

第三方元件的來構造的原因,因為這種寫法下面,兩者沒有本質的差別!

下面是部分<code>Nancy.Swagger</code>裡面的核心内容,也是上一篇所沒有的特殊之處。

AsSwagger是RouteDescription一個擴充方法,這個方法是傳回我們需要的PathItem。

OperationId是這個路由的一個友好名稱,源碼裡面的字段定義表明它要唯一。對更加詳盡的描述可能去看Swagger中對這些參數的說明!

Tag可以了解為這個路由屬于那個分組,起分隔符的作用,舉個例子,現在有A,B兩個子產品的API,我們肯定不能把它們交叉排列下去

而是A的放到一個地方,B的一個地方,便于我們的的區分。

Summary是目前路由的精簡描述,要小于120個字元。

Description是目前路由的較長的描述。

Response是期望的運作結果的相關内容,可以有多個,這裡沒有标明狀态碼,而是直接寫處理的内容,此時說明這裡用的是預設的狀态碼。

Response裡面又是一個委托,裡面又有部分定義:

Schema表明目前響應應該傳回的類型是什麼

Description是這個響應對應的描述資訊

這個時候是會出錯的,因為我們在Respoonse的時候指定了Schema,但是我們并沒有指定它的定義。

我們需要先在MetadataModule中引用ISwaggerModelCatalog這個接口并調用它的AddModel方法把相關的類型添加進去,這樣才能正常運作!

示例結果如下:

先來看看上面設定對應的内容:

淺析如何在Nancy中使用Swagger生成API文檔

點選Try it out運作的結果

淺析如何在Nancy中使用Swagger生成API文檔

可以看到使用curl 去通路我們的實際接口拿到伺服器的響應資訊(結果和頭部)

在終端執行一下這個指令,也是這個結果。

淺析如何在Nancy中使用Swagger生成API文檔

同樣的,先在Module中定義一個路由,這個路由包含了一個Path參數和一個Query參數

這裡作了多一點操作,為的是示範盡可能多的用法。如果傳遞的産品id為空,則直接傳回404。如果沒有輸入isActive這個Query參數

傳回Productr的IsActive就為false。

然後在MetadataModule中添加相應的描述

這裡多了一個Parameter是上面沒有提到的,這個就是我們的請求參數,這裡的請求參數包含下面五種:

Path

Query

Body

Header

Form

下面是運作的效果圖,分别示範了下面幾種情況

不填productid,不能執行,輸入框會變紅

填了productid,能執行,但是伺服器端傳回的isactive是false

填了productid和isactive,能執行,伺服器傳回的isactive是true

淺析如何在Nancy中使用Swagger生成API文檔

當然現在在MetadataModule的參數還有其他的寫法

可以用Parameters直接将所有的參數,組合成一個集合來進行處理。

此時的效果和上面是一樣的。

在Module中添加一個新增商品的方法,這個方法包含兩種請求參數,一種是正常POST的json格式的資料,一種是請求頭,對于請求頭,隻是判斷了一下用戶端發起的請求有沒有包含相應的請求頭就是了,并沒有做嚴格的判斷。同時為了示範多種MIME類型的傳回結果,這裡相容了json和xml格式的傳回結果。

同樣的,MetadataModule中添加如下的描述:

BodyParameter是我們在POST等操作時用的,它需要指定我們POST的資料格式(Schema那裡的類型),為了示範添加請求頭資訊,是以這裡也加了一個必填的請求頭資訊。

ConsumeMimeType表示我們發起請求的資料格式必須是json格式的,當然也可以支援多種不同的資料格式。

ProduceMimeTypes表示服務端響應時支援的資料格式,這裡指定了json和Xml也是為了和我們Module中的内容相對應。

示範效果:

淺析如何在Nancy中使用Swagger生成API文檔

有時候,API的界限分的不是很清晰或者有交集的時候,可能會出現這樣的情況:一個api會屬于多個分組。

前面我們都是直接指定了一個tag,也就表示上面的隻是對應一個tag。

先來定義一個方法,用于示範多分組和過時、廢棄的API

Metadata内容

效果如下:

淺析如何在Nancy中使用Swagger生成API文檔

雖說已經标記為過時了,但是本質這個方法還是存在,是以也是能正常調用的。

Swagger支援3種安全認證折方式:APIKEY、Basic、OAuth2.0,同樣的<code>Nancy.Swagger</code>也支援,不過有點坑就是了。

使用的話有兩個步驟(這裡用最簡單的APIKEY示範):

Step 1: 引用定義,在Bootstrapper中添加驗證相關的内容

Step 2 : 在MetadataModule中添加描述

當然,目前是沒有辦法正常運作的!此時運作效果如下:

淺析如何在Nancy中使用Swagger生成API文檔

單獨打開/api-docs這個路徑時提示如下錯誤:

淺析如何在Nancy中使用Swagger生成API文檔

這個十有八九是<code>Nancy.Swagger</code>的安全驗證存在bug的,這個項目沒有足夠多的單元測試可能也是導緻問題的一部分原因。

發現的主要bug是在MetadataModule中使用<code>SecurityRequirement(SecuritySchemes.ApiKey)</code>時一直在報錯,報錯内容如下:

Nancy.RequestExecutionException: Oh noes! ---&lt; System.InvalidCastException: Unable to cast object of type 'Swagger.ObjectModel.SecuritySchemes' to type 'System.String'. at Swagger.ObjectModel.SwaggerModel.SwaggerSerializerStrategy.ToObject(IDictionary source)

于是調試源碼,發現在Swagger.ObjectModel項目下的ToObject方法有問題

從上面的出錯内容也能清楚的看到,SecuritySchemes不能轉成string的,其中SecuritySchemes是一個枚舉類型。

為了能正常運作,肯定要修改驗證一下!!于是修改成如下 :

由于在Mac上無法打開這個項目,是以上面的修改是切換回windows完成的。

進行上面的修改後,項目是已經能正常運作了!但是卻少了一個很重要的東西!

淺析如何在Nancy中使用Swagger生成API文檔

在這個方法裡面加了APIKEY驗證的,但是小鎖的标記卻沒有出來!

之後對比了Swagger的官方示例http://petstore.swagger.io/

淺析如何在Nancy中使用Swagger生成API文檔

居然有這麼坑爹的事情!security是一個數組啊,不是一個對象啊~~

後面就修改了Nancy.Swagger裡面的許多代碼(瞎改的,隻為了能正常運作),涉及了好幾個類檔案,就不一一說明了。

第一個問題已經提了PR到這個項目了,第二個問題還沒找到比較滿意的方案,暫時沒提。

直接上最後的效果圖,分别示範了,沒有驗證,驗證成功和驗證失敗這三種情況!

淺析如何在Nancy中使用Swagger生成API文檔
注:本文隻示範了其中Nancy.Swagger的其中一種用法,而且還有部分内容是沒有涉及到的。還有兩種其他用法有時間會拿出來和大家分享。

在過程中還有一個需要十分注意的地方(本來這個應該是在上一篇提及的):就是XXModule和XXMetadataModule相對應的位置關系。

Nancy在這裡限制的比較死,強制了下面三種情況:

Module所在的位置

MetadtaModule應該在的位置

./BlahModule

./BlahMetadataModule

./Metadata/BlahMetadataModule

./Modules/BlahModule

../Metadata/BlahMetadataModule

這是檔案分布所要注意的問題。

還有一個命名應該注意的問題:當我們對一個Module起名為ProductsModule時,它對應的MetadataModule一定要是ProductsMetadataModule。

而不能是其它,有一次由于粗心,忘記把s字母帶上,花了不少時間去找原因~~

上述兩個問題的答案在<code>Nancy.Metadata.Modules</code>項目的DefaultMetadataModuleConventions類中。

<code>Nancy.Swagger</code>給我們API文檔化的道路上帶來了不少的便利之處,除了安全驗證這一塊的問題有點坑,其他的算是比較正常,用起來也還算簡單。

對于Swagger來說,通用性很好,隻要提供的指定格式的資料就能很好的渲染出讓人舒适的界面,或許這就是它這麼流行的一個關鍵點吧。

下面是一張腦圖簡單的概括相關的内容 :

淺析如何在Nancy中使用Swagger生成API文檔

本文已同步到Catcher寫的Nancy彙總部落格:Nancy之大雜燴

淺析如何在Nancy中使用Swagger生成API文檔

如果您認為這篇文章還不錯或者有所收獲,可以點選右下角的【推薦】按鈕,因為你的支援是我繼續寫作,分享的最大動力!

作者:Catcher Wong ( 黃文清 )

來源:http://catcher1994.cnblogs.com/

聲明:

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。如果您發現部落格中出現了錯誤,或者有更好的建議、想法,請及時與我聯系!!如果想找我私下交流,可以私信或者加我微信。