一種單入口的API框架設計方式(新手向)
前言
在日常開發中,Web API是大多數開發者都會接觸到的技術,如微信公眾號開發、騰訊雲的對象存儲COS等。
API的調用方式千差萬別,有些使用傳統的GET、POST表單的方式來傳遞鍵值對信息(如微信公眾號開發中的大部分介面),有些則是使用時下比較流行的RESTFul風格(如騰訊雲對象存儲COS的大部分介面),還有的就是直接傳遞一個raw data,這樣的原生數據一般都是json格式(如本文講解中使用的方式)。
而無論這些API的調用方式怎麼變化,當有單入口(或者隱含了單入口)的設計時,本文或許就可以為你提供一些設計思路。
介面說明
為了說明單入口API的設計方式。在這裡,先對本文API的調用方式進行一個基本的說明。
在本文中,參數主要通過post方式傳遞一個json格式的raw data數據。該json的格式如下:
{ "op" : "operator", "param" : { "param1" : "value1", "param2" : "value2" }}
其中,op為需要調用的方法,param中為該方法需要的參數。當然這裡是一個最基礎的參數結構,如果需要驗證調用者的合法性之類的判斷的話也可以加入一些參數用於相關判斷。
提示: 在不同語言不同主流web框架中基本都有獲取raw data的方式,比如在PHP中可以通過
file_get_contents(php://input);
方法獲取。
核心內容
設計需求
一般來說,一個完整的項目需要有合理的結構,而不會都放到唯一的一個文件中(應該沒人會這麼干吧……)。因此,在單入口的調用方式中,需要有一種合理的機制進行請求數據的分發方式來調用對應的功能。
其中一種直截了當的方式是構建op與對應方法的映射關係,通過管理Dict或者Associative array來手動綁定對應的調用。當然這種方法比較繁瑣,而且還不夠優雅。
在這裡,我主要說明一種利用動態語言的特性來優雅簡潔地實現請求分發的方案。
基本原理
前面介紹了一大堆,其實真正的核心內容則非常簡單:其實主要就是利用了動態語言或者反射的特性, 通過op動態得創建類, 並且動態得調用相應的構造方法。下面主要介紹在PHP中如何實現這樣的設計。
在PHP中存在一個 ReflectionClass 類,使用它可以根據類名的字元串獲取到對應的PHP 類對象。於此同時,在該類中可以獲取到某個類的 方法參數列表 ,且能夠進行動態調用。利用這三點即可以實現動態化的過程。至於如何實現……先來看下面的代碼示例吧:
<?php// 示例類,為介面需要調用的方法class hello{ function __construct($name) { $this->name = $name; } function action() { echo "Hello $this->name."; }}// 從json數據中獲取基本信息$json = {"op" : "hello", "params" : {"name" : "xia"}};$data = json_decode($json, true);$op = $data[op];$params = $data[params];// 通過反射機制獲取類對象, 從這裡開始是核心機制$class = new ReflectionClass($op);// 獲取構造函數的參數列表$construct = $class->getMethod(__construct);$paramNames = $construct->getParameters();# 對參數進行排序,用於保證調用構造函數時的順序$newParams = [];foreach ($paramNames as $paramName){ $newParams[] = $params[$paramName->name];}# 創建hello對象$myHello = call_user_func_array([$class , newInstance], $newParams);$myHello->action();
可以看到,這段代碼除了在json數據中,其他任何地方都沒有出現需要創建類的信息。類名以及構造函數的參數都可以在json中指定並進行動態生成。
有了這套機制後,基本的介面參數分發便已經完成了。
當然,僅僅是這樣還算不上設計實現一套完整的API框架。為了使框架更加完善,擁有更強的擴展性,還需要有更多的處理。
基本的參數完整性檢查
施工中
多文件夾的支持(重寫autoload方法)
施工中
工廠方法的使用
施工中
這是我在知乎中發表的第一篇文章, 難免會有各種錯誤或者遺漏的地方,有不足之處希望能指出來,謝謝!!!
推薦閱讀:
※Python中階建議之使用自定義類來代替字典的作用
※假如你可以個人主導 C++,你打算怎樣裁剪、擴充和訂製 C++ 來達到你心中最完美的 C++?
※一起寫一個解釋器(1)---一些廢話
※如何學習編程語言?