目前,先後端分離的開發模式愈來愈受到你們的青睞,前端與後端的職責也更加清晰,後端經過 API 提供數據,前端經過 API 獲取數據,展現頁面,前端有更大的發揮空間、後端也能夠更加專一於數據處理。php
在這樣的時代大背景下,我嘗試從後端的角度出發,經過一系列文章,探討後端開發人員應該如何交付高質量的 API 接口,減小溝通成本,下降「聯調」可能出現的問題,保證代碼質量以及項目定期完成。前端
就目前個人面試經驗而言,絕大部分項目都沒有引入自動化 API 測試,測試基本都是依靠開發人員的自測以及測試人員黑盒測試。本文不探討黑盒測試,僅僅發表一點我對自動化 API 測試的想法。laravel
首先,在我來看,缺乏自動化 API 測試可能存在如下問題:git
API 實現與設計不符,好比缺乏字段或者字段類型不正確github
API 沒法造成完整閉環,缺乏功能,「聯調」還須要不斷修改面試
新加功能可能致使已有 API 出現 BUG,手動迴歸測試耗時且繁瑣thinkphp
API 測試是一個比較大的主題,本文主要就「如何讓 API 的實現與設計相符合」這一點出發,說一說個人想法及開發 Json Validator 的心路歷程。json
早在兩年多之前,就在思考如何作 API Schema 的測試,保證 API 返回的結果與預期的一致。當時發現了 Json-Schema 這個工具,也研究了一番,但上手成本仍是略高,最終並無實質的產出什麼東西。後端
而後去年在開發 Blink Framework 的 API 測試組件的時候,發現 Laravel 中 驗證 Json 的用法,很簡潔優雅,同時 Codeception 也有相似的組件。api
因而我就在想,有沒有可能結合這兩種方式的優勢,本身開發一個 Json Validator,保持嚴謹的同時儘量簡單易用。
正好2017新的一年,公司產品須要對外提供新的 Open API,方便與合做廠商就行業務對接。我認爲這是一個實驗和推行新 API 測試方式的時機,因而便利用假期的時間,開發出了 Json Validator 的原型,讀者能夠在 rethinkphp/json-validator 查看它的最新代碼。
Json Validator 經過簡單的語法定義 Json 結構,而後驗證給定的數據是否知足預約義的 Json 結構,比 Json-Schema 更加簡單易用。
除了保證設計的簡潔優雅外,Json Validator 引入類型系統的概念,經過開發者自定義類型,實現類型的複用與自由組合,讓 Json 的驗證更方便高效,只要一個項目的基礎類型定義好了,剩下基本搭積木組裝便可。
Json Validator 默認提供7種內置類型,他們分別是: integer
, double
, boolean
, string
, number
, array
和 object
。開發者也能夠定義本身的複合數據類型,以下的例子定義了一個 User
複合類型:
$validator->defineType('User', [ 'name' => 'string', 'gender' => 'string', 'age' => '?integer', ]);
這個 User 類型有三個屬性,name、gender 和 age,其中 name 和 gender 都是 string
類型,age 爲 integer
類型,但容許爲 null
。這裏咱們在類型的前面加一個 ? 表示該字段能夠爲 null
。
除了定義複合數據類型,咱們也能夠定義列表類型,好比定義一個 UserCollection
的類型,它是一個數組,數組的每一個元素都是 User:
$validator->defineType('UserCollection', ['User']);
要定義一個列表類型,類型的定義必須是隻有一個元素的數組,數組的第一個元素即該列表類型所容許容納的類型。
對於複雜應用場景,咱們也可使用 PHP 的 callable
來定義更靈活的類型,以下咱們定義一個 timestamp
的類型,它驗證給定的值必須是合法的時間字符串。
$validator->defineType('timestamp', function ($value) { if ((!is_string($value) && !is_numeric($value)) || strtotime($value) === false) { return false; } $date = date_parse($value); return checkdate($date['month'], $date['day'], $date['year']); });
定義好了數據類型以後,咱們就能夠驗證給定的數據是否符合定義,若是不符合定義,Validator 會給出錯誤信息。
use rethinkphp\jsv\Validator; $validator = new Validator(); // $validator->defineType(...) Add your custom type if necessary $matched = $validator->matches($data, 'User'); if ($matched) { // Validation passed } else { $errors = $validator->getErrors(); }
在一些場景下,咱們但願咱們定義的類型與給定的數據徹底匹配,不須要多餘的字段,這個時候可使用 Json Validator 的嚴格模式:
$data = [ 'name' => 'Bob', 'gender' => 'Male', 'age' => 19, 'phone' => null, // This property is unnecessary ]; $matched = $validator->matches($data, 'User', true); // strict mode is turned on var_dump($matched); // false is returned
這個例子就會驗證失敗,由於 phone 字段在 User
中並無定義。
本文介紹了我開發 Json Validator 的背景和過程以及它的簡單用法,但我也在想它的使用場景可能不只侷限於此,下面是我對其將來的一些想法:
類型系統與文檔生成工具相結合,從代碼直接生成 API 文檔的數據模型部分
自動生成 Json-Schema 定義文件,跨語言使用更方便
經過生成 Json-Schema 定義文件,實現自描述 RESTFul API
未完待續...
本文首發於「代碼寫詩」微信公衆號及同名知乎專欄
掃描二維碼關注「代碼寫詩」公衆號
微信公衆號: https://mp.weixin.qq.com/s/cN...
知乎專欄: https://zhuanlan.zhihu.com/p/...