Swagger - 先後端分離後的契約

先後端分離

按照如今的趨勢,先後端分離幾乎已是業界對開發和部署方式所達成的一種共識。所謂的先後端分離,並非傳統行業中的按部門劃分,一部分人只作前端(HTML/CSS/JavaScript等等),另外一部分人只作後端(或者叫服務端),由於這種方式是不工做的:好比不少團隊採起了後端的模板技術(JSP, FreeMarker, ERB等等),前端的開發和調試須要一個後臺Web容器的支持,從而沒法將先後端開發和部署作到真正的分離。html

一般,先後端分別有着本身的開發流程,構建工具,測試等。作前端的誰也不會想要用Maven或者Gradle做爲構建工具,一樣的道理,作後端的誰也不會想要用Grunt或者Gulp做爲構建工具。先後端僅僅經過接口來協做,這個接口多是JSON格式的RESTFul的接口,也多是XML的,重點是後臺只負責數據的提供和計算,而徹底不處理展示。而前端則負責拿到數據,組織數據並展示的工做。這樣結構清晰,關注點分離,先後端會變得相對獨立並鬆耦合。可是這種想法依然仍是很理想化,先後端集成每每仍是一個很頭痛的問題。好比在最後須要集成的時候,咱們才發現最開始商量好的數據結構發生了變化,並且這種變化每每是在所不免的,這樣就會增長大量的集成時間。前端

歸根結底,仍是前端或者後端感知到變化的時間週期太長,不能「及時協商,儘早解決」,最終致使集中爆發。怎麼解決這個問題呢?咱們須要提早協商好一些契約,並將這些契約做爲能夠被測試的中間產品,而後先後端都經過自動化測試來檢驗這些契約,一旦契約發生變化,測試就會失敗。這樣,每一個失敗的測試都會驅動雙方再次協商,有效的縮短了反饋週期,而且下降集成風險。具體的實踐方式,請參加我同事的一篇博文,「先後端分離了,而後呢?」http://icodeit.org/2015/06/whats-next-after-separate-frontend-and-backend/git

不過,僅僅靠紀律是不夠的,還須要經過工具的輔助來提升效率。下面,咱們就來看一下,一個API設計工具——Swagger,將如何幫助咱們更好的實現「先後端分離」。github

Swagger

Swagger包括庫、編輯器、代碼生成器等不少部分,這裏咱們主要講一下Swagger Editor。這是一個徹底開源的項目,而且它也是一個基於Angular的成功案例,咱們能夠下載源碼並本身部署它,也能夠修改它或集成到咱們本身的軟件中。npm

在Swagger Editor中,咱們能夠基於YAML語法定義咱們的RESTful API,而後它會自動生成一篇排版優美的API文檔,而且提供實時預覽。相信大多數朋友都遇到過這樣一個場景:明明調用的是以前約定好的API,拿到的結果卻不是想要的。可能由於是有人修改了API的接口,卻忘了更新文檔;或者是文檔更新的不及時;又或者是文檔寫的有歧義,你們的理解各不相同。總之,讓API文檔老是與API定義同步更新,是一件很是有價值的事。下面咱們經過一個例子來感覺一下Swagger給咱們帶來的好處。後端

首先咱們須要安裝一個Swagger Editor,或者也能夠直接使用在線版本http://editor.swagger.io/。若是須要在本地啓動編輯器,執行如下三行命令便可(前提是已經安裝好了Node.js):api

git clone https://github.com/swagger-api/swagger-editor.git
cd swagger-editor
npm start

當咱們修改了API的定義以後,在編輯器右側就能夠看到相應的API文檔了,並且永遠是最新的。網絡

Swagger editor

不只如此,它還可以自動生成Mock server所須要的代碼,這樣一來前端開發就不再用等着後端API 的實現了。除此以外,它還有一個更強大的功能,甚至可以幫助咱們自動生成不一樣語言的客戶端的代碼。Swagger是基於插件來實現各類不一樣的語言的,因此,若是已經提供的語言中沒有你正在用的,你也能夠本身實現相應的插件,甚至是從源代碼級別進行定製化。數據結構

Swagger generate client

契約測試

談到了先後端分離,那麼在所不免,會遇到一些集成的問題:一撥人在全心全意的進行前端開發,另外一撥人在心無旁騖的作後端開發,那麼誰應該爲集成買單呢?在如今這個持續集成、持續交付的年代裏,咱們應該如何去保證雙方不會分道揚鑣、越走越遠呢?前後端分離

因此,在一開始就定一個契約就成了迫在眉睫的事情,雙方就API相關的內容,包括路徑、參數、類型等達成一致,固然,這份契約並非一旦建立就不能修改的,並且,若是一開始沒有設計好,頗有可能會頻繁的修改。這個時候,要讓雙方都可以實時的跟蹤最新的API就成了一個難題。還好,在總結了前人的經驗和教訓以後,咱們早已有了應對之策,那就是契約測試

老馬(Martin Fowler)早在2011年的時候就發表了一篇博客http://martinfowler.com/bliki/IntegrationContractTest.html,專門討論瞭如何作契約測試。

首先,咱們先假設咱們已經有了一份契約,多是基於JSON格式的,有多是基於XML格式的,這都不重要。而後,前端會根據這份契約創建一個Mock server,全部的測試都發往這個Mock server。有兩方面的緣由:一是這個時候可能後臺的API尚未開發完成;二是有可能由於網絡等其餘方面的緣由致使直接調用真實的後臺API會很不穩定或者很耗時。到這裏,可能有人就要說了,若是後臺的API實現和以前約定的並不同,怎麼能保證到了集成的時候雙方還能很順利的集成呢?其實這個問題並不難,只須要讓前端的測試按期鏈接真實的API執行一遍就能儘早的發現差別性。比方說,在咱們日常的build pipeline上添加一個job,讓這些測試天天在午夜裏連着真實的API執行。若是,次日發現這些測試有的失敗了,那麼就須要和開發後臺API的人員進行一次溝通了,頗有可能因爲真實的業務邏輯發生了變化,API在實現的時候,已經和以前的契約不一致了,若是是這樣,那麼相應的測試和契約定義就須要更新以知足最新的業務需求。

總之,進行契約測試的目的就是儘早的發現差別性,並做出調整,將最後集成的風險降到最低。

相關文章
相關標籤/搜索