所有 /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. 如果基於成本考慮, 以上兩條作廢. 誰更改簡單誰做更改. 因為前後端是一個團隊. 事情完不成, 誰都別想好過.


從最終呈現上來看不合理

說實話這種情況在真實項目中挺常見的,有以下幾個原因

1.可能是歷史遺留問題,一個是先開發的,另一個是後來提需求後加的,但是沒重構

2.也可能這是兩個人開發的,事先沒進行溝通

3.後端系統非常臃腫,從眾多api中找一個已經開發過的api,還不如重新命名再搞一個


作為前端,看到這樣的介面會讓他改


推薦閱讀:
相关文章