我是前端,後端給的介面獲取所有項目和獲取篩選項目的介面不一樣這樣合理嗎?
所有 /api/v1/project/list?page=1
篩選 /api/v1/project/listfilter?id=xxname=xxpage=1
我覺得這樣問題也不大,但是如果要設置分頁查詢有點麻煩但也能做,我想不明白的是為什麼不把這兩個介面合併為一個。
不合理,且不符合REST風格。
URL(Uniform Resource Locator)是統一資源定位用的,同一個資源應該有相同的URL。就像你家不應該有兩個地址一樣。
而且,具體到問題描述中的API定義還存在一個錯誤,是題主沒有意識到的。就是不應該出現list或listfilter,因為這兩個單詞不是資源,是多餘的。
想想Windows資源管理器,有一個文件夾叫project,下面直接存放project文檔就可以了,不需要在project下面再創建一個叫list的子文件夾。所以:
訪問一組資源,應該是:D:xxxxxxproject
訪問其中一個資源,應該是:D:xxxxxxprojectxxx.docx
具體到你的例子,應該是:
定位一組資源,應該是:/api/v1/project/?name=xxpage=xx,其中name參數是可選無默認值的,page是可選有默認值的。
定位其中一個資源,應該是:/api/v1/project/id
伺服器端為什麼不這樣寫,原因太多了。我猜最可能的原因是他們不知道name如何作為可選參數,或者覺得判斷有沒有name太麻煩...
伺服器端這種程序員我見多了,你去找他們理論,他們會反過來理直氣壯質問你:這樣能用嗎?這樣能用嗎???
評論區 @Forgotten提出參數過多的問題。我覺得規定伺服器端方法的參數不能超過5個可以,但是不能規定URL的參數數量。
在Get請求的時候,參數過多確實比較麻煩。特別是綜合查詢的時候,查詢條件太多,參數十幾個到幾十個都有可能。這時候,我們可以用option-bag模式。不要把參數作為Primitive類型散開,而是收集到一個對象(POJO)里。下面用Java伺服器端Spring MVC框架舉例。
例如,User表,有name、age、sex、mail、address,language6個查詢參數。
API的URL還是這樣:
http://server-host:port/api/user?account=xxxage=xxsex=xxmail=xxxaddress=xxlanguage=xxx
現在前端框架發送AJAX請求,都有方便的辦法把一個JS對象轉換成URL問號後面的參數。所以,其實上面URL後面的六個參數,在前端框架里也是一個JS對象。傳到伺服器端,也有一個對象對應它。
下面是伺服器端代碼
定義一個UserCriteria POJO:
final class UserCriteria {
private String name;
@Min(0)
private int age;
// ...其他參數定義
private UserCriteria() {
}
public int getName() {
return name;
}
public int getAge() {
return age;
}
}
加一個ControllerAdvice
@ControllerAdvice
class BindingControllerAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
}
Controller里就可以這麼寫了(只有一個參數):
@GetMapping
List& searchUsers(@Valid UserCriteria userCriteria) {
return userRepository.search(userCriteria);
}
不合理。
一旦介面有變動,就要維護兩個介面。
不合理.
- 前端是後端的消費方, 後端應該滿足前端的介面需求;
- 前端不關心後端的實現細節, 前端只關心後端提供的介面輸入什麼, 輸出什麼;
- 如果基於成本考慮, 以上兩條作廢. 誰更改簡單誰做更改. 因為前後端是一個團隊. 事情完不成, 誰都別想好過.
從最終呈現上來看不合理
說實話這種情況在真實項目中挺常見的,有以下幾個原因
1.可能是歷史遺留問題,一個是先開發的,另一個是後來提需求後加的,但是沒重構
2.也可能這是兩個人開發的,事先沒進行溝通
3.後端系統非常臃腫,從眾多api中找一個已經開發過的api,還不如重新命名再搞一個
作為前端,看到這樣的介面會讓他改
推薦閱讀: