[译] RESTful API 设计指南 - 最佳实践

BitLuminaryX
• 阅读 306

[译] RESTful API 设计指南 - 最佳实践

原文: RESTful API Designing Guidelines — The Best Practices

Facebook、Google、GitHub、Netflix 和其他一些科技巨头都为开发人员和产品提供了通过 API 来使用它们的数据。

即使你不为其他开发者或产品提供 API,但通过精细设计的 API 对你的应用也是有益的。

关于 API 设计的最佳实践争论了很长时间,并没有一个官方的定义。

API 是开发人员与数据进行交互的接口。 一个精心设计的 API 应该是易于使用的。

术语

下面列出来的是与 REST API 相关的重要术语。

  • 资源(Resource) 实体对象或由一些相关联数据及可对其操纵的方法组成的事物。例如:动物、学校和员工都是资源。增删改查是对这些资源执行操作的方法
  • 集合(Collections)一组资源,例如 companies 是 company 的集合
  • URL用来定位资源和执行操作的路径

API 终端(endpoint)

我们通过公司员工的例子来理解。

/getAllEmployees 是一个 API 来获取员工列表。围绕着公司的其他一些 API 如下:

  • /addNewEmployee
  • /updateEmployee
  • /deleteEmployee
  • /deleteAllEmployees
  • /promoteEmployee
  • /promoteAllEmployees

诸如此类不同操作的 API endpoint 会很多很多。大家会注意到每个 API endpoint 都包含了动作(action)的描述,当 API 增加时 API endpoint 将会变得越来难以维护。

错在哪里?

URL 应该只包含资源(名词),而不应该有动作(action)或动词。API /addNewEmployee 包含动作 addNew 和资源名 Employee

正确的方式是什么?

/companies 是一个不包含动作的好例子。但问题是“我们怎么告诉服务器该对companies资源执行增删改查?”

这就是 HTTP 方法(GET、POST、PUT、DELETE)派上用场的时候了。

资源名应该始终使用复数形式,如果想查看一个实例,可以通过在 URL 中传递一个 ID。

  • GET 方法 /companies:获取所有公司列表
  • GET 方法 /companies/34:获取 ID 为 34 的公司详细信息
  • DELETE 方法 /companies/34:删除 ID 为 34 的公司

其他例子,如果一个资源(resources)在另一个资源(resource)下,例如:一个公司的员工。

  • GET /companies/3/employees ID 为 3 的公司所有员工列表
  • GET /companies/3/employees/45 ID 为 3 的公司里 ID 为 45 的员工信息
  • DELETE /companies/3/employees/45 删除 ID 为 3 的公司里 ID 为 45 的员工
  • POST /companies 创建新的公司,并返回新创建的公司详细信息

现在的 API 是不是更清晰一致呢?

结论

路径中的资源以复数形式存在,并通过 HTTP 方法对资源进行操作。

HTTP 方法

HTTP 定义了一些方法来指示对资源的操作。

  1. GET 获取资源数据,并不带有副作用。例如:/companies/3/employees 返回 ID 为 3 的公司里所有的员工列表。
  2. POST 请求服务器在数据库中创建资源。例如:/companies/3/employees 给 ID 为 3 的公司创建新的员工。POST 是非幂等的。
  3. PUT 请求服务更新资源或创建一个不存在的资源。例如:/companies/3/employees/john 更新或创建 ID 为 3 的公司下 employees 集合里的 johnPUT 是幂等的。
  4. DELETE 请求从数据库中删除某个资源。例如: /companies/3/employees/john/ 从 ID 为 3 的公司 employees 集合里的 john

HTTP 响应状态码

当客户端通过 API 请求服务器时,不论成功与否都应该知道反馈结果。

HTTP 状态码是几组在不同状况下给出说明的标准化代码,服务器应该返回正确的状态码。

2xx(成功)

表示服务器已经接收并成功处理了请求。

  • 200 OK — 表示 GET、PUT 或 POST 成功
  • 201 Created — 当有新的资源被创建时应该返回该状态码。例如:通过 POST 创建新资源,要返回 201
  • 204 No Content — 表示请求已被成功处理但没有返回任何内容。例如:DELETE /companies/43/employees/2 删除 ID 为 2 的员工,删除成功后我们不需要返回任何数据。如果出现错误,如 employee 2 在数据库里不存在,返回码就不应该是 2xx Success,而是 4xx Client Error

3xxx(重定向)

  • 304 Not Modified — 表示数据已被缓存。

4xx(客户端错误)

这些状态代码表示客户端发送了错误的请求。

  • 400 Bad Request — 表示请求不能被处理,因为服务器不理解客户端发起的请求。
  • 401 Unauthorized — 不允许客户端访问的资源,需要使用凭证(credentials)请求
  • 403 Forbidden — 表示请求有效并通过了身份认证,但出于某个原因不允许访问
  • 404 Not Found — 表示资源不可用或找不到
  • 410 Gone — 表示资源已被永久删除,注意与 404 区别,资源以前存在但现在不存在会用 410 替代 404

5xx(服务器错误)

  • 500 Internal Server Error — 表示请求有效,但是服务器端出现问题
  • 503 Service Unavailable — 表示服务器宕机不能接收和处理请求。一般用在服务器维护期间

搜索、过滤、排序和分页

这些操作只是对数据集的查询。我么需要在 GET API 中附加查询参数。

  • 排序 — 如果想获取有序的公司列表。GET /companies 应该接受多个排序查询参数。例如:GET /companies?sort=rank_asc 按公司升序排名排序
  • 过滤 — 过滤数据集,通过传不同的查询参数。例如:GET /companies?category=banking&location=india 过滤出来在印度所属银行分类下的所有公司
  • 搜索 — 例如:通过公司名搜索公司 GET /companies?search=Digital Mckinsey
  • 分页 — 当数据很多时,需要将数据进行拆分。例如:GET /companies?page=23

如果 GET 请求的参数过长,服务端可能会返回 414 URI Too long 状态码,这时我们可以通过 POST 方式并将参数放在请求体(body)里。

版本控制

通过版本控制来升级你的 API,例子:http://api.yourservice.com/v1/companies/34/employees,如果有大版本升级,可以命名新的 API 版本 v2v1.x.x


「极客阅读 」汇聚了国内外最优质的技术博客、产品动态、公众号文章。开发者可以在极客阅读一站式的阅读到来自互联网技术大咖的文章。

「极客阅读 」官网:geeker-read.com

[译] RESTful API 设计指南 - 最佳实践

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
RESTful API 设计最佳实践
WebAPI近几年变得越来越火,而简洁的API设计在多后端系统交互应用中也变得尤为重要。通常,会使用RESTfulAPI来作为我们的WebAPI。本文介绍了几种简洁RESTfulAPI设计的最佳实践。使用的名词而不是动词使用名词来定义接口!(https://static.oschina.net/uploads
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
BitLuminaryX
BitLuminaryX
Lv1
细想出智慧,细嚼出滋味。
文章
3
粉丝
0
获赞
0