RESTful接口设计

最近看了RESTful接口设计的最佳指导,这里总结下。

每个资源对应两种URL

/employees    # 集合url
/employees/56  # 元素url

标示资源,使用名词而不是动词

不好的例子如下,这会导致方法数量激增,也更加复杂,后期维护麻烦。

/getAllEmployees
/getAllExternalEmployees
/createEmployee
/updateEmployee

使用http方法来操作资源。

GET /employees
GET /employees?state=external
POST /employees
PUT /employees/56

对于资源来说,4个http方法GET, POST, PUT, DELETE,来完成最常见的CRUD操作(Create新建, Read查询, Update更改, Delete删除)。

  • Read: 查询某个资源,是最常见的形式,使用GET方法来查询资源。GET请求不会改变资源的任何状态,是幂等的。可以看做只读的操作,这里可以进行缓存以加快查询速度。
  • Create:新建资源。使用POST方法来创建一个新的资源。
  • Update:更改资源。使用PUT方法来更改一个存在的资源。
  • Delete: 删除资源。使用DELETE方法来删除某个资源。

因此2个URL加上4个方法,我们就可以得到8种不同的操作。

POST (新建) GET (查询) PUT (更改) DELETE (删除)
/employees 创建一个新的员工 查询所有员工 批量修改员工信息 删除所有员工信息
/edployees/56 返回错误 查询56号员工 修改56号员工信息 删除56号员工

对集合URL使用POST方法来创建一个新的资源

RESTful接口设计_第1张图片
对集合URL使用POST方法来创建新资源
  1. 客户端使用集合URL的POST方法,HTTP body里携带新资源信息,例如员工名字Albert Stark;
  2. 服务端收到后,按内部逻辑保存成功后会生成该资源的唯一标示号21,返回给客户端一个成功的回复。回复包中header中包含一个Location ,表示如何访问刚刚创建的资源。客户端拿该地址,可访问刚刚新建的员工。

对元素URL使用PUT方法来修改一个资源

RESTful接口设计_第2张图片
使用put方法来更新资源
  1. 发送一个PUT请求给元素url,body中携带需要更新的内容;
  2. 服务端更新21号员工信息,返回状态码200和最终结果。

使用复数形式的名词

这里推荐使用复数单词。不要单数和复数混合使用。

使用查询字符来完成可选参数或复杂参数

让接口保持简单,将复杂的参数迁移到查询字符串中去。

GET /employees?state=internal&maturity=senior

使用HTTP状态码

RESTful服务可以提供一系列的HTTP状态码来标识当前请求的结果。

  • 2xx,表示成功相关。
  • 4xx,表示客户端错误。例如客户端参数错误,验证失效等。
  • 5xx,表示服务器错误。服务器端发生错误。
2xx 3xx 4xx 5xx
200, 成功 301,地址永久移动 400,错误请求 500,服务器内部错误
201,已创建 304,未改变 401,未认证
403,禁止访问
404,资源不存在

提供足够的错误信息

在回复中尽量提供详细的错误信息。
请求访问高权限:

GET /employees?state=super

回复400.

// 400 Bad Request
{
"message": "You submitted an invalid state. Valid state values are 'internal' or 'external'",
"errorCode": 352,
"additionalInformation" : "http://www.domain.com/rest/errorcode/352"
}

返回的json属性使用驼峰命名法

js的客户端会常常自动将回复中的json结果转换为js的对象,使用下划线连接(year_of_birth)或大写(YearOfBirth)可能会导致出现一些问题。

person.year_of_birth //导致错误
person.YearOfBirth //构造方法
person.yearOfBirth //比较规范

在URL中强制携带版本号

在URL中强制携带一个版本号。当接口有改变时,可以部署在下一个版本中而不影响之前的旧接口。用户端可以自行选择何时迁移使用新接口,不用担心接口会时刻变化。

/v1/employees

提供分页

查询资源时,不管是对后台还是客户端,一下全部返回所有数据都不是一个好的选择。因此,需要提供分页机制。返回给客户端的结果中要包含当前分页、总共的分页等信息,以方便客户端遍历。

使用动词表示非资源型回复

有时候发起请求并不牵涉任何资源,这时候使用动词来表示更好。

GET /translate?from=de_DE&to=en_US&text=Hallo
GET /calculate?para2=23¶2=432

提供链接信息以便能在接口间访问(HATEOAS)

这里的核心思想就是提高可维护性,降低耦合性。使得客户端在后台进行URI的更改时,依然可用。

//...
   {
      "id":1,
      "name":"Paul",
      "links": [
         {
            "rel": "salary",
            "href": "/employees/1/salaryStatements"
         }
      ]
   },
//...

上面的回复中,一个员工的信息中包含的是一个地址,而不是值。我们需要访问该地址来拿到薪水。这样多加了一层,会提供可维护性和扩展性。但会多进行网络传输。

参考:

  • https://blog.philipphauer.de/restful-api-design-best-practices/

你可能感兴趣的:(RESTful接口设计)