使用ASP.NET Core 3.x 构建 RESTful API - 3.1 API资源命名
為了與RESTful API進行交互,API消費者需要使用到三個概念:?
資源的標識。也就是可以找到資源的URI。?
HTTP方法。例如GET,POST等等,這些方法是HTTP協議的一部分。?
有效載荷(可選),英文就是Payload。例如,當你想創建資源的時候,HTTP請求里面會包含著你想要創建的資源的一個表述。或者當獲取資源的時候,HTTP響應里面會它的Body里面包含著資源的表述。這些表述的格式就是我們使用的media?type,例如application/json。?
?
之前講了RESTful?API的統一資源接口這個約束,里面提到了資源是通過URI來進行識別的,每個資源都有自己的URI。URI里還涉及到資源的名稱,而針對資源的名稱卻沒有一個標準來進行規范,但是業界還是有一些最佳實踐的。那么我們首先看看這些最佳實踐對資源命名是如何建議的。?
?
資源命名??
使用名詞,而不是動詞?
一個資源的URI代表的是一個實際上或概念上存在的東西,因此,它應該是名詞,所以也就不應該出現動詞,動詞應該使用HTTP方法來表達。?
?
需求:我們看這樣一個需求的例子:“我想獲得系統里所有的用戶”。?
常見錯誤做法:你可能把API的URI設計成這樣:api/getusers。這樣的設計是不好的,因為里面出現了一個動詞get。?
分析:這個句話的主要動詞就是“獲取”,而想要獲取的資源(也就是主要的名詞)是“用戶”。?
正確的做法:需求里面主要的動詞應該通過HTTP方法來體現,“獲取”對應的HTTP方法就是GET。而“用戶”這個資源可以用英文user或者users來表示(是否使用復數一直存在爭議,兩種方法都行,但你在使用的時候需要保持一致)。所以正確的uri應該是?GET?api/user。?
?
人類能讀懂?
還是上面那個需求:“我想獲得系統里所有的用戶”。?
我們可以把uri設計成?api/u?或者?api/ur。但是這樣設計的話,對API的消費者來說非常的不友好,因為不能直觀的看出來它到底代表的是什么資源,可能是user,也可能是university。?
所以建議的做法是要足夠友好,并且比較簡短,例如:api/users。?
?
要體現資源的結構關系?
假設如果后端API系統里面有若干種資源,而用戶這個資源與其它的資源并沒有直接的關系,這樣的話獲取用戶資源的uri應該是?api/users。而不是?api/products/users,也不是api/catalogs/products/users,因為user和product或者catalog沒有直接的關系。?
通過id獲取單個用戶的uri應該是:api/users/{userId},而不是api/userid/users。?
這樣寫的好處是可以讓API具有很好的可預測性和一致性。?
?
需求1:系統里有兩類資源,公司(Company)和員工(Employee),它們倆是包含關系,也就是一個公司包含多個員工。現在我想獲取某個公司下所有的員工信息。?
分析:這里的主要動詞還是“獲取”,所以我們可以使用HTTP的GET。而這里的資源有兩個,分別是公司和員工,而且它們是包含關系:一個公司包含多個員工或者說一個公司是一個員工的集合。所以API的URI在設計的時候需要體現這種包含關系。?
常見的錯誤做法:如果你想獲得公司這個資源,我想你現在應該不會出錯,uri應該是?api/companies。而想要獲取某個公司下的員工,常見的錯誤做法有:api/employees,api/employees/{companyId}等等。這些設計非常不好是因為它無法體現出Company和Employee之間的結構關系。?
建議的做法:需要體現Company和Employee之間的關系,所以uri應該是GET?api/companies/{companyId}/employees。這樣做直接體現出了Company和Employee之間的結構關系,而且也體現出了一個Company就是一個Employee的集合體。?
?
需求2:我想獲取某個公司的某個員工信息。?
常見的錯誤做法:api/employees/{employeeId},api/companies/{employeeId}等等。這些做法都無法體現出Company和Employee之間的關系。?
建議的做法:api/companies/{companyId}/employees/{employeeId}。?
?
自定義查詢怎么命名?
我們經常會遇到這樣的需求,比如獲取按照某個資源排序后的資源,或者按照某些條件過濾后的資源。這時候應該怎對資源進行命名呢??
?
需求:“我想獲取所有的用戶信息,并要求結果是按年齡從小到大進行排列的”。?
常見錯誤的做法:api/users/orderby/age。之前說了,uri里面使用的都應該是名詞,如果按照這個uri的結構來看,那么orderby和age就應該是另外兩個資源,并且users包含orderby,orderby包含age,這顯然是錯誤的。?
建議的做法:api/users?orderby=name,這樣設計更合理一些。這里使用了query?string作為查詢參數進行排序。?
?
例外?
有一些需求總是無法滿足的達到RESTful的約束。?
需求:“我想獲取系統里所有用戶的數量”。?
妥協的做法:我們確實可以先通過?GET api/users來獲取系統里所有的用戶信息,然后再算出用戶的數量,但是這樣做也太浪費資源并且效率也太低了。我們也很難使用某個名詞來表示這個需求的資源。例如:api/users/totalamountofuser。這樣的uri按理說就代表著我們將會獲取到一個集合資源,里面是一堆數字,但針對這個需求,我也沒有特別好的辦法讓uri命名完全符合RESTful的約束,所以針對這個需求,我使用的就是這個uri。?
Microsoft Learn的官方教程《使用 ASP.NET Core 創建 Web API》請點擊原文鏈接。
總結
以上是生活随笔為你收集整理的使用ASP.NET Core 3.x 构建 RESTful API - 3.1 API资源命名的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式应用框架 Dapr
- 下一篇: .NET Core on K8S 学习与