代碼規範-對接口規範的一些思考

背景

本人所在公司爲外包公司,先後端人員沒有固定的組合,都是跟着項目走的,因而全部的後端/前端開發人員交流不順暢,每一個人對接口的理解不同,致使了在開發過程當中接口聯調須要耗費大量時間。團隊內部開會討論接口規範化的問題,做爲前端人員,我提出了本身的見解,在此供你們參考。javascript


怎樣進行接口規範化

由於每一個人對本身使用語言有不一樣的理解、HTTP協議熟悉程度不一樣、思惟邏輯、開發經驗不同。對接口規範有想法的人應該提出本身的觀點,給出本身的理由。讓別人去評價,討論出一套統一的規則,最終統一成一個內部的標準。 造成統一標準後由相關人員寫出示例。例如前端要對GET請求針對jQuery.ajaxfetchaxios等請求庫給出示例代碼。之後直接參照示例代碼進行開發。html

因爲每一個項目在定義接口時有許多不一樣的方式,我根據以往的經驗,從請求方法、請求頭、請求體、響應狀態碼、響應體等幾個方面對接口的規範說說本身的見解。前端

我對標準的理解

咱們不一樣的項目使用的請求方式大概有兩種:java

  • GET、POST
  • GET、POST、PUT、DELETE

若是使用前者,POST的URL中應該指明要執行的動做,然後者不須要指定。ios

POST /api/user/add HTTP/1.1
POST /api/user/set HTTP/1.1
POST /api/user/delete HTTP/1.1

# 這裏例子中約定PUT是新增,POST是修改 POST /api/user HTTP/1.1 PUT /api/user HTTP/1.1 DELETE /api/user HTTP/1.1 複製代碼

至於使用前者仍是後者,我更傾向於前者。 若是使用後者時,什麼狀況下使用POST、什麼狀況下使用PUT,搜索到了到了一些資料,但看不懂。git

接口URL

接口URL應該見名知意,有必定的規律。 這裏我不太懂,就不作過多贅述。github

數據類型的約定

前端請求中不該該有undefined,由於後端不支持(json也不支持)該數據類型。 若是Content-Typemultipart/form-data,前端不該該傳null,由於會被轉化成字符串,後端不能判斷出這是用戶輸入仍是null類型。ajax

每一個項目應該約定請求時下面這些數據表明什麼意思json

  • null數據類型表示什麼
  • 空字符串類型表示什麼

GET請求

做用

GET請求應該讀取數據,不該該產生任何的「反作用」操做。 這裏要注意一點瀏覽器對URL長度是有限制的,若是查詢的URL長度過長會引發不可預期的後果。能夠採用POST/PUT進行查詢。axios

方式

GET請求的參數應該放在請求的URL中而不該該放在請求體中。 例以下面是一個標準的這個GET請求(不相關HTTP頭字段已剔除)

GET /api/user?userId=12345 HTTP/1.1
Host: http://www.example.com
複製代碼

POST/PUT/DELETE請求

這三種請求方法傳參數格式都相同,下面以POST爲例。 POST類型使用的方式很是多樣,見識過各類各樣奇葩的方式,也是耽誤時間最長的,嚴重影響開發進度。這裏只討論我認爲標準的方式。

做用

POST請求用於新增、修改或刪除數據,少數狀況下用於查詢數據。

方式

POST請求的參數必須放在請求體中。 而POST的請求方式有四種方式

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

這幾種方式經過HTTP頭中的Content-Type頭字段進行控制。

multipart/form-data

咱們如今使用的最多的是multipart/form-data

POST /api/user/set HTTP/1.1
Host: http://www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2KbanAZwv0mKceX0

------WebKitFormBoundary2KbanAZwv0mKceX0 Content-Disposition: form-data; name="userName" 張三 ------WebKitFormBoundary2KbanAZwv0mKceX0 Content-Disposition: form-data; name="userId" 123456 ------WebKitFormBoundary2KbanAZwv0mKceX0-- 複製代碼

這種方式不適合複雜數據類型的傳遞,例若有個接口須要同時修改多個用戶:

const userList = [
  {
    userID: 123,
    userName: '張三',
    isAdmin: true,
  }, {
    userID: 456,
    userName: '李四',
    isAdmin: false,
  },
];
複製代碼

那麼在POST請求時只能這麼作

POST /api/userlist/set HTTP/1.1
Host: http://www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2KbanAZwv0mKceX0

------WebKitFormBoundary2KbanAZwv0mKceX0 Content-Disposition: form-data; name="userID" 123,456 ------WebKitFormBoundary2KbanAZwv0mKceX0 Content-Disposition: form-data; name="userName" 張三,李四 ------WebKitFormBoundary2KbanAZwv0mKceX0 Content-Disposition: form-data; name="isAdmin" 1,0 ------WebKitFormBoundary2KbanAZwv0mKceX0-- 複製代碼

更重要的是這種方式不支持數據類型,傳入的全部格式的數據都會轉成字符串類型。後端常常要使用1表示true,須要將數組或對象拆分開。

application/json

這是我推薦使用的方式,有效的彌補了multipart/form-data的缺陷。 但不知什麼緣由如今咱們團隊基本不使用這種方式。 application/json也有一個缺陷就是不支持上傳文件(有特殊的方法這裏也不建議使用),想上傳文件仍是使用multipart/form-data

下面是請求示例

POST /user HTTP/1.1 
Host: http://www.example.com
Content-Type: application/json;charset=utf-8

[{"userID":123,"userName":"張三","isAdmin":true},{"userID":456,"userName":"李四","isAdmin":false}]
複製代碼

響應

不知道服務器對於不一樣的處理會返回什麼樣的狀態碼,這裏不作討論。 咱們會返回一個邏輯狀態碼code與提示信息msg,響應體像下面這樣。

{"code":200,"msg":"處理成功!","data":{}}
複製代碼

在此基礎上增長一些限制:

建議data字段始終爲對象類型

易於擴展,例如當前接口是用戶列表頁,data使用數組。v2版本接口加入了分頁查詢,就必須使data變爲對象類型了。

若是字段爲複雜類型,不容許爲null

複雜類型包括數組與對象。 爲了方便閱讀,這裏將json字符串轉化爲了JS對象。

const resBody = {
  code: 200,
  msg: '處理成功',
  data: {
    list: [
      {
        userID: 123,
        userName: '張三',
      },
    ],
  },
};
複製代碼

若是沒有數據的時候返回

const resBody = {
  code: 200,
  msg: '處理成功',
  data: {
    list: null,
  },
};
複製代碼

這樣前端在遍歷list時,null會致使代碼出錯,應該始終保證該字段的數據類型不變,正確返回方式以下。

const resBody = {
  code: 200,
  msg: '處理成功',
  data: {
    list: [],
  },
};
複製代碼

其餘

若是你有其餘補充或糾正,歡迎👏評論。

參考資料

相關文章
相關標籤/搜索