最近準備重寫公司一箇舊項目,每次想起這個項目,內心總忍不住要吐槽一波,難受。具體細節就不說了,水平不一樣,見仁見智,也不是本文的重點。就是此時,技術leader說要把接口設計成RESTful規範,我拒絕了
,這東西適合當前業務開發嗎?先後端對接麻煩嗎?前端
這東西之前上學時就據說過,但工做也沒看見有人徹底以此設計web
我也想遵照這傳說中的規範,可現實不容許啊json
REST(Representational State Transfer),直譯爲表現層資源轉換,具體就不說了hhh,相關文章一大堆,但REST感受沒有一個十分明確的標準,更趨向於一種接口設計風格
,按照基本的約束條件進行開發設計。後端
有人說RESTful API能夠一會兒讓別人知道這個url是幹什麼的,但說到底不就是取決於咱們的接口命名嗎?接口作到見名知義
,用良好的英文命名,不也能達到效果。因此,參考業界部分規範,我定義了以下命名。api
拿通用的訂單模塊舉例,最基礎無非是兩種場景-獲取列表
or 獲取詳情
數據結構
/api/order/orderList
/api/order/orderInfo
前面不加get?架構
以前我也加,時間久了總以爲礙眼hhh,這裏定義get,service層又定義一個相同或差很少的方法名,總以爲在 重複命名
。爲了讓接口路徑更短更精簡,乾脆省略get,後面就約定以 list/info結尾
就認爲是獲取數據信息了。
不學RESTful在數據實體後加s表示複數?app
對於後端 數據結構
而言,List更合適有些前端須要作列表展現,List翻譯後更 見名知義
以s結尾的單詞需加es就不說了,有些單詞是單複數同行,若是加s我會以爲這人英文語法不行啊,不加又像單數。因此爲了統一,List最好
有時咱們的核心業務需求不定,相同的實體信息在不一樣場景須要提供不一樣的數據,其實到咱們後端就是根據不一樣過濾條件查詢出實體信息,有些所謂的RESTful規範說是在url後加參數信息,如:編輯器
/orders?state=finish&userId=123
url
這也是我不喜歡RESTful的緣由之一,某些場景下,過濾信息是固定不變的,不能經過前端傳參決定
,並且url後帶參數的傳參也有弊端。
回到不一樣場景不一樣命名,最好能從產品用戶角度
出發,好比:
/api/order/myAllOrderLIst
/api/order/finishiedOrderLIst
/api/order/invoiceOrderList
若是作後臺管理系統這種項目,確實能夠用list、info、save、update、delete一把梭了。每一個數據實體一定要有這些方法
myBatis-plus封裝好了一些service、mapper方法,增刪改查都有十分規範的命名。並且在相同的操做都有適合本身的命名。
動做 | service | mapper(dao) |
---|---|---|
增 | save | insert |
刪 | remove | delete |
改 | update | update |
查 | get/list | select |
有些接口須要兼容不一樣的APP版本,若是增長字段不能知足,無可奈何需增長新的請求路徑,可加個v一、v2版本前綴
,原接口名不變,加個版本前綴還能夠看到接口的歷史修改,方便維護。
/api/order/v1/orderInfo
/api/order/v2/orderInfo
除了場景的GET、POST請求註解,Spring還有@PutMapping 、@PatchMapping、 @DeleteMapping 註解,標識不一樣的請求方式。
不只如此,SpringMVC還支持參數綁定。
@RequestMapping(value = "/orders/{id}", method = RequestMethod.GET)
public void getById(HttpServletRequest request, @PathVariable("id") Long id){
System.out.println(id);
}
複製代碼
這....又給咱們提供一種獲取參數的形式..............
既然拒絕了RESTful,那咱們規定,前端統一用json形式POST請求接口傳遞參數,後端攔截器拿到請求,自定義ApiRequst類,將請求信息(請求頭/請求體)統一封裝,這樣先後端架構都保持統一,更有利於聯調。
@Data
public class ApiRequest implements Serializable {
private String appVersion; //請求頭-app版本號
private Integer deviceType; //請求頭-設備類型
private String deviceName; //請求頭-設備類型
private String secret;
private String token;
private Map data; //請求體-業務參數
}
複製代碼
Controller層統一形式接收
/**
* TestApi
* @param apiRequest
* @return
*/
@PostMapping(value = "/testList")
public ApiResponse testList(ApiRequest apiRequest) {
Long id = apiRequest.getDataParamAsLong("id", 0L);
String name = apiRequest.getDataParamAsString("name", "");
return ApiReponse.ok();
}
複製代碼
其實我不並反對RESTful
,僅僅想說出本身的想法。存在即合理嘛。我也曾經嘗試過其規範,真是一把辛酸淚。我以爲只有適合本身的業務,能提升開發效率、先後端溝通效率的,就是良好的規範,規範並無一個十分統一的參考
。
咦,好像還漏了接口返回結果Response沒說吧,這在RESTful裏貌似也有說起。