對外公開 Web API 時,必須首先思考將怎樣的信息或數據經由怎樣的 API 對外公開。接下來就讓我們來考慮一下如何決定對外公開的功能和端點,以及 Web API 的端點該如何設計。
從本章開始,我們將講解 API 具體的設計規則及方法。
### API 端點的設計思想
在 Web API 的語境里,端點是指用于訪問 API的 URI。一般而言,因為 API 將各種不同的功能進行了封裝,所以會擁有多個不同的端點。實現不同的功能就需要分別賦予其不同的端點,即訪問這些功能的 API 所需的 URI。
比如,在設計獲取用戶信息的 API 時,可以分配如下 URI,API 用戶可以通過訪問端點使用 API 提供的功能。
~~~
https://api.example.com/v1/users/me
~~~
#### 端點的基本設計
要探討什么是優秀的 URI 設計,有一個非常重要的原則,如下所示。
~~~
容易記憶,URI 包含的功能一目了然。
~~~
API 是供計算機程序機械地訪問的,但是還需要人眼看上去也易于理解,設計出便于開發人員理解的端點可以有效降低開發人員搞錯 API 端點或錯誤使用 API的概率。這不僅可以提高開發人員的生產效率,還有助于提升 API 的口碑。
設計優美的 URI 的方法,我們可以總結出如下幾個普適又重要的原則。
? 短小便于輸入的 URI
? 人可以讀懂的 URI
? 沒有大小寫混用的 URI
? 修改方便的 URI
? 不會暴露服務器端架構的 URI
? 規則統一的 URI
接下來讓我們結合 API 的設計思想逐一了解以上這些原則。
1. 短小便于輸入的 URI
在表示的信息量相同的情況下,使用短小、簡單的表述方式更易于理解和記憶,并能減少輸入時的錯誤。
~~~
http://api.example.com/service/api/search
~~~
該 URI 和下面這個簡短的 URI 所包含的信息基本沒有什么差別。
~~~
http://api.example.com/search
~~~
2. 人可以讀懂的 URI
為了避免設計出這樣難以理解的 URI,首先就要做到不輕易使用縮寫形式,雖然有人認為這些縮寫形式對于母語是英語的人而言非常常見,但即使這樣,也不建議過度使用省略和縮寫形式。因為使用 API 的開發人員的母語未必是英語。使用全世界通用的英語來描述可以使 API 更易于理解。
另外,即使看起來是同一個縮寫形式,也存在細微的差別,比如表示國家名稱的“jp”“jpn”等。使用標準化的“代碼”體系來標識,比使用其他符號會更易于理解。
要設計容易理解的 URI,就要使用 API 里常用的英語單詞。
對于 API 里常用的單詞,人們往往已經形成共識,一般會默認“該單詞是用來表示某某功能或某某信息的”,因此,使用 API 里常用的單詞,有助于讓人僅通過 URI就能理解它的意思。
要設計容易理解的 URI,第 3 個要點就是要盡可能地避免拼寫錯誤。對于母語非英語的人而言,這一點尤其應引起注意。
易于理解的 URI 還可以減輕用戶編寫訪問 API 的代碼時的負擔。因為如果從URI 就能知道該 API 的用途,那么開發人員在閱讀訪問該 API 的代碼時,就可以不用每次都去翻閱 API 的相關文檔,從而大幅提高了工作效率。另外,這也會減少開發人員因 URI 難以理解而訪問了錯誤的 URI 進而訪問了錯誤的 API 的情形。
3. 沒有大小寫混用的 URI
不要使用如下例所示的大小寫混用的 URI,一般建議全部使用小寫字母的形式。
~~~
http://api.example.com/Users/12345
http://example.com/API/getUserName
~~~
大小寫字母混用會造成 API 難以理解,容易讓人搞錯。因此需要統一為全部大寫或全部小寫,一般標準的做法是全部使用小寫。
另外,統一使用小寫字母和忽略字母大小寫從嚴格意義上來說仍有區別。忽略字母大小寫時,也是就說,在訪問大小寫字母混用的 URI 時,是不是應該將其統一視為小寫字母,進行相同的處理并返回相同的結果呢?
~~~
http://api.example.com/USERS/12345
http://api.example.com/users/12345
~~~
對于上面的 URI,可以有多種處理方式:
1. 無論訪問哪個 URI 都一并返回相同的結果;
2. 將混有大寫字母的 URI 重定向到只有小寫字母的 URI 進行處理;
3. 將混有大寫字母的 URI 視為錯誤的 URI 并簡單地返回 Not Found;
4. 不識別混有大寫字母的URI,等等。
普通的 Web 頁面的情況下,如果采用“無論訪問哪個 URI 都一并返回相同的結果”這種處理方式,Google 等搜索引擎便會認為有多個頁面返回了相同的結果,從而導致網頁排名(PageRank)下降。因此,對于普通的 Web 頁面而言,采用返回 301 代碼并將頁面進行重定向的方法最為合適。因為 API 不會涉及搜索引擎的可搜索性等問題,所以頁面排名下降的問題并不存在。
HTTP 協議里原本就規定了 URI“除了模式(schema)和主機名以外,其他信息都需要區分字母的大小寫”(RFC 7230)。因此,只要端點描述使用了小寫字母,混入大寫字母時就理所當然地會出錯,關于這一點可以說不會有任何疑問。
4. 修改方便的 URI
“修改方便”即英語中所說的“Hackable”。“修改方便的 URI”指的是能將某個URI 非常容易地修改為另一個 URI。假設我們需要獲取某種商品(item,根據 API類型的不同而發生變化),該 API 的端點如下所示。
~~~
http://api.example.com/v1/items/12346
~~~
從以上 URI 能直觀地看出該商品 ID 為 123456,并且可以猜測只要修改這一ID,就能訪問到其他商品的信息。
6. 規則統一的 URI
這里提到的規則是指 URI 所用的詞匯和 URI 的結構等。對外提供 Web API 時,僅用一個或一種規則來描述端點的情況很少見,多數情況下都會公開多個 API 端點。
在本章開篇提及的 SNS 在線服務的范例里就提供了獲取好友信息、發送消息等多種功能的 API。如果這些 API 分別采取相同的規則進行設計,結果會如何呢?
如果使用如下所示的規則統一的 URI,便會很容易理解。
? 獲取好友信息
~~~
http://api.example.com/friends/100
~~~
? 發送消息
~~~
http://api.example.com/friends/100/message
~~~
在以上示例里,獲取好友信息的 API 里使用了 friends 這樣的復數形式,ID信息通過查詢參數進行傳遞。