基於上面的這些原因,我們知道 File API 為什麼能夠如此成功。事實上,它是如此的成功以至於今天的 *-nix 操作系統,everything is filed based.
儘管我們有了一個非常好的例子 File API,但是要設計一個能夠長期保持穩定的 API是一項及其困難的事情,因此僅有一個好的參考還不夠,下面再試圖展開去討論一些更細節的問題。
在一個面向服務化/Micro-service 化架構的今天,一個應用依賴大量的服務,而每個服務 API 又在不斷的演進過程中,準確的記錄每個欄位和每個方法,並且保持更新,對於減少客戶端的開發踩坑、減少出問題的幾率,提升整體的研發效率至關重要。
如果適合的話,選用「資源」加操作的方式來定義。今天很多的 API 都可以採用這樣一個抽象的模式來定義,這種模式有很多好處,也適合於 HTTP 的 RESTful API 的設計。但是在設計 API 時,一個重要的前提是對 Resource 本身進行合理的定義。什麼樣的定義是合理的? Resource 資源本身是對一套 API 操作核心對象的一個抽象Abstraction。
抽象的過程是去除細節的過程。在我們做設計時,如果現實世界的流程或者操作對象是具體化的,抽象的 Object 的選擇可能不那麼困難,但是對於哪些細節應該包括,是需要很多思考的。例如對於文件的API,可以看出,文件 File 這個 Resource(資源)的抽象,是「可以由一個字元串唯一標識的數據記錄」。這個定義去除了文件是如何標識的(這個問題留給了各個文件系統的具體實現),也去除了關於如何存儲的組織結構(again,留給了存儲系統)細節。
雖然我們希望API簡單,但是更重要的是選擇對的實體來建模。在底層系統設計中,我們傾向於更簡單的抽象設計。有的系統裡面,域模型本身的設計往往不會這麼簡單,需要更細緻的考慮如何定義 Resource。一般來說,域模型中的概念抽象,如果能和現實中的人們的體驗接近,會有利於人們理解該模型。選擇對的實體來建模往往是關鍵。結合域模型的設計,可以參考相關的文章,例如阿白老師的文章【2】。
與前面的一個問題密切相關的,是在定義對象時需要選擇合適的 Level of abstraction (抽象的層級)。不同概念之間往往相互關聯。仍然以 File API 為例。在設計這樣的 API 時,選擇抽象的層級的可能的選項有多個,例如:
這些不同的層級的抽象方式,可能描述的是同一個東西,但是在概念上是不同層面的選擇。當設計一個 API 用於與數據訪問的客戶端交互時,「文件 File 「是更合適的抽象,而設計一個 API 用於文件系統內部或者設備驅動時,數據塊或者數據塊設備可能是合適的抽象,當設計一個文檔編輯工具時,可能會用到「文本圖像混合對象」這樣的文件抽象層級。
又例如,資料庫相關的 API 定義,底層的抽象可能針對的是數據的存儲結構,中間是資料庫邏輯層需要定義數據交互的各種對象和協議,而在展示(View layer)的時候需要的抽象又有不同【3】。