在繁雜的業務需求中,如何找到API設計的平衡點

  • 2019 年 11 月 11 日
  • 筆記

這是學習筆記的第 2150 篇文章

關於API設計,有什麼好的設計方法,或者說如何來構建一個相對健壯的後端API設計體系?我覺得還是在不斷的實踐中犯低級錯誤逐步積累起來的,或者是到了不得不改的時候才會造成這種變革和重構的過程。

比如說現在服務的後端有20個介面,基本人為還可以做好基本的配置管理。而一旦接入了業務流程,很多對象實體(模型)層產生了狀態交互,那麼這個複雜度就會高很多,而在邏輯實現或者API邏輯實現中,這塊就很容易產生一個問題,那就是不斷打修補程式。

比如A的狀態變更,會導致B狀態變更,B的狀態變更會導致C狀態變更,在程式裡面就需要不斷的調整,添加邏輯。如果這樣的關係越來越複雜,人為是很難統一管理起來的,基本上就處於崩潰的邊緣,疲於應付,一種就是增加無窮無盡的API,滿足業務需求,成為典型的密集型,另一種情況就是修正無窮無盡的業務邏輯問題,成為一團亂麻。

我們目前的情況沒這麼糟糕,但是從擴大的業務需求和維護管理來看,已經逐步顯示出不少問題。

那麼回過頭來,我們來想一個本源的問題?

什麼樣的API設計是好的設計,公認的一種實現就是File API 的主要介面(以C為例,很多是 Posix API,選用比較簡單的I/O介面為例

  1. int open(const char *path, int oflag, …/*,mode_t mode */);
  2. int close (int filedes);
  3. int remove( const char *fname );
  4. ssize_t write(int fildes, const void *buf, size_t nbyte);
  5. ssize_t read(int fildes, void *buf, size_t nbyte);

為什麼File API 是經典的好 API 設計?

  • File API 已經有幾十年歷史(從1988年算起,已30年),儘管期間硬體軟體系統的發展經歷了好幾代,這套 API 核心保持了穩定。
  • API 提供了非常清晰的概念模型,每個人都能夠很快理解這套API背後的基礎概念:什麼是文件,以及相關聯的操作(open, close, read, write),清晰明了;
  • 支援很多的不同文件系統實現,這些系統實現甚至於屬於類型非常不同的設備,例如磁碟、塊設備、管道(pipe)、共享記憶體、網路、終端 terminal 等等。這些設備有的是隨機訪問的,有的只支援順序訪問;有的是持久化的有的則不是。然而所有不同的設備不同的文件系統實現都可以採用了同樣的介面,使得上層系統不必關注底層實現的不同,這是這套 API 強大的生命力的表現。

我來總結下在API設計中自己感悟的一些小技巧,比如我們對於業務開放介面,不希望有20個功能,開放20個不同的介面,可能對於業務來說,我開放一個介面或者少數幾個介面就行,而對於參數等可以根據不同的邏輯場景有所差別,比如下面的API,有一個統一的訪問入口,比如是v1/api/user_info

對於這個API下面我們可以定義一系列的相關介面,可以通過不同的code來定義區別。

另一個層面來看,我們設計的Model或者Object實體,其實從數據模型層設計來看,無非就是對於數據對象的增刪改查操作,而這些增刪改查操作也會隨著實體的屬性複雜度情況而提供相應的方法。

對於業務訪問來說,其實是希望從業務視角來進行抽象,比如創建用戶,修改用戶資料,銷戶等操作,都是在業務層面來定義的,隨著這些變化,會涉及相關的對象實體變化,而這樣基於流程的變更也更貼近業務場景。

所以整個邏輯串聯起來就會是下面這樣的流程,而在這個過程中我們需要對已有的model層面進行細化的設計,對於model層面的增刪改查屬於內部的API,而對接業務層的則是FlowControl部分的API,他們有著不同的定位和許可權隔離,比如對外業務我們不能提供Model層的增刪改查介面,而需要統一交由流程層來進行對接。

小結:

在需求不清晰,管理混亂之中,需要找到工作的平衡,而需要更持久有效的管理,和這些管理設計是分不開的。