2010年前,大型社群網站如騰訊QQ、新浪微博都搭建了開放平臺。中小型網際網路公司接入開放平臺,能夠獲取社交平臺的海量使用者,有效的降低獲客成本,獲得社交平臺的其他能力。對於使用者而言,用一個社交帳號登入各種網站或APP,體驗也會更好。後來,許多行業如電商、金融等都開放了業務核心API。這些行業的競爭非常激烈,公司希望通過開放平臺與合作伙伴保持更高效的共同作業,實現資源交換或者流量變現。
廣義的開放平臺是個龐大的結構,它站在核心業務系統的前面,承接著所有的流量。公司所有的使用者端比如Web站點、手機APP、智慧硬體都對接開放平臺API,只是各自的許可權不同,可以存取的資源不同。狹義的開放平臺只是開啟了一扇門,讓合作伙伴進來參與業務互動。從業務層面上看,開放平臺僅僅是流量渠道之一。
本文重點討論的是狹義的開放平臺。
業務系統相當於酒店,開放平臺是專門招待外賓的特殊客房,合作伙伴(以下統稱商戶)就是外賓。外賓進入酒店有專門的通道,不和其他客戶的共用。外賓可以在房間睡覺、點餐,但是不能去其他房間串門。主觀上,酒店希望接納更多的外賓,但是招待能力始終有上限,因此一定要限制外賓活動的頻率,否則沒有足夠的人力招待其他的住客。在系統設計上,開放平臺有四個重要的要求:
開放平臺的使用者只有兩個:商戶和平臺管理員,平臺管理員可以劃分為超級管理員、商務經理、產品經理。
商戶的開發水平和意願不一樣,接入方式可以分為三種:
商戶服務系統至少包含商戶入駐、引數設定功能,部分業務還需要佣金結算、訂單統計等功能。
商戶管理系統主要用於查詢、修改、編輯商戶資訊、審批商戶的設定資訊以及其他輔助功能。
採用成熟的分散式元件實現架構,如下圖所示:
為了業務的整體可控,核心業務系統不應該迎合開放平臺的變化,而是開放平臺適配核心系統。開放平臺的業務邊界是只做渠道功能,不做核心業務,通過呼叫核心系統的介面完成業務操作。
核心系統沒有意願儲存商戶ID或者其他與渠道有關的資料,資料閉環是指商戶發起的請求(比如建立訂單),先儲存在開放平臺的資料庫,開放平臺再向核心系統發起請求。這份資料並不需要特別完整,但是至少包含業務主鍵。當有需要的時候,通過查詢核心系統介面來彌補缺失的資料。自主冗餘資料的好處有兩點:1.減少了呼叫鏈,加快介面查詢速度;2.更容易實現根據商戶ID分頁查詢資料、訂單統計、佣金結算等功能。
介面設計遵循 RESTful 協定,它有下面的特性:
採用RESTful API的好處有三點:
在實際的運用中,嚴格遵循 RESTful 協定有下面三點缺陷:
開發人員使用過多的HTTP動詞,心智負擔較大;用動詞標記操作資源滿足不了複雜的業務需求,最後還得通過介面名稱來區分;某些請求如 PUT、DELETE 可能被中間層裝置過濾掉。
URL裡面包含引數預留位置比如GET /Api/Orders/{id}/OrderItems/{id}
,閱讀性不佳。如果根據 URL 來統計介面呼叫次數,分析系統需要額外處理相同地址不同引數的情況。
通過20X、30X、4XX、5XX等有限的響應碼無法表達複雜的業務狀態。
為了解決以上三點缺陷,建議介面遵循如下規範:
通常每個介面都有一個資源地址,為了更靈活些,可以設計為僅有一個入口地址,在引數裡面增加介面名稱,來區分不同的業務操作。參考淘寶API文檔,如下所示:
請求地址:http://gw.api.taobao.com/router/rest
請求引數:
名稱 | 型別 | 必須 | 描述 |
---|---|---|---|
method | String | 是 | API介面名稱,例如:taobao.user.buyer.get |
timestamp | String | 是 | 時間戳,格式為yyyy-MM-dd HH:mm:ss,時區為GMT+8,例如:2015-01-01 12:00:00 |
遵循MECE原則,根據業務領域進行介面分類。
MECE(發音me see)是Mutually Exclusive Collectively Exhaustive的縮寫,意思是「相互獨立,完全窮盡」,也就是對問題的分析,能夠做到不重複、不遺漏,從而直達問題的核心,並找到問題的解決方法。由《金字塔原理》作者巴巴拉·明託1973年發明,也是麥肯錫思維過程的一條基本準則。
不同版本的相同介面,將版本號標識統一後置,如下所示:
# 老版本
http://openapi.test.com/order/create_order
# 新版本
http://openapi.test.com/order/create_order/v2
所有介面的返回資料都採用固定的JSON格式,如下所示:
{
"code":200,
"msg":"OK",
"data":{
"order_id":"2012120112304512",
"product_name":"男士衛衣"
}
}
對所有API請求引數(包括公共引數和業務引數,但除去sign引數、值為空和值為陣列型別的引數),根據引數名稱的ASCII碼錶順序升序排列,比如:foo=1, bar=2, foo_bar=3, foobar=4排序後的順序是bar=2, foo=1, foo_bar=3, foobar=4。
將排好序的引數名、引數值用&拼裝在一起,採用utf-8編碼,比如:bar=2&foo=1&foo_bar=3&foobar=4。
在拼裝的字串尾部加上預先分配的金鑰值 secret_value 後,再進行MD5演演算法摘要,如:md5(bar=2&foo=1&foo_bar=3&foobar=4&secret=secret_value)。
加密敏感資料比如使用者資訊,常見加密演演算法可以是RSA或者AES。
在介面存取的前置層,只允許在白名單裡的IP的請求。商戶通過商戶服務系統自行管理IP白名單。
資料推播是指系統主動通知商戶資料的變化,滿足部分商戶對資料的實時性要求。舉個例子,商戶建立訂單成功,通過訂單查詢介面GET http://openapi.domain.com/query_order
獲得訂單狀態。如果商戶希望儘快知道訂單狀態,可以定時輪詢訂單查詢介面,但是效率低且浪費資源。系統主動通知商戶訂單的狀態,能有效解決這個問題。商戶需要按規範開發介面,接受指定格式的資料。資料推播增加系統了的複雜性,又會造成兩個問題:
訂單有多個狀態而且有業務順序性,由於網路延遲的未知性,訂單狀態資料可能無序的推播給商戶,這時商戶可以通過業務邏輯去保證訂單狀態的正確性。
系統推播資料一般採用MQ非同步傳送,即便有手段保證訊息不丟失,但是商戶的網路故障依然會造成推播失敗。這種故障有兩個方式解決:1.系統在T+1時段提供T日的對賬檔案,裡面包含訂單號和訂單狀態,商戶根據對賬檔案批次更新遺失的訂單號狀態;2.商戶定時輪詢訂單狀態。
為了便於商戶查閱和測試API,採用 https://www.apifox.cn/ 管理API檔案。