REST API 设计规范(下)

简介: REST API 设计规范(下)
  • 标头版本控制
    不是追加版本号作为查询字符串参数,而是可以实现指示资源的版本的自定义标头。 此方法需要客户端应用程序将相应标头添加到所有请求,虽然如果省略了版本标头,处理客户端请求的代码可以使用默认值(版本 1)。 下面的示例使用了名为 Custom-Header 的自定义标头**。 此标头的值指示 Web API 的版本。
GET https://adventure-works.com/customers/3 HTTP/1.1
Custom-Header: api-version=1
  • 无版本控制:在更改RESTful API时,请以兼容的方式进行更改,并避免生成其他API版本。

说明:多个版本会使理解、测试、维护、发展、操作和发布我们的系统变得非常复杂。

在更改RESTful api时,请以兼容的方式进行更改,并避免生成其他API版本。多个版本可能会显著地复杂化查看、测试、维护、发展、运营和发布系统(补充阅读)。如果无法以兼容的方式更改API,请使用这三种方式:

  • 在旧资源变体的基础上创建新资源(变量)
  • 创建一个新的服务端点-即一个具有新API的新应用程序(使用新域名)
  • 在微服务中创建一个新的API版本,该版本支持与旧API同时支持
Filtering

在参数过滤时通常会为参数值定义数据格式。为了在所有 API 中提供一致的开发者体验并减少学习曲线,API 设计人员必须使用以下扩展巴科斯范式(Extended Backus-Naur Form,简写为“EBNF”)语法的变体来定义这样的语法:

Production  = name "=" [ Expression ] ";" ;
Expression  = Alternative { "|" Alternative } ;
Alternative = Term { Term } ;
Term        = name | TOKEN | Group | Option | Repetition ;
Group       = "(" Expression ")" ;
Option      = "[" Expression "]" ;
Repetition  = "{" Expression "}" ;

注意TOKEN 表示在语法之外定义的终端符号。

Example

GET /zoos?id=1001,1002,1003

Long running

有时,POST、PUT、PATCH 或 DELETE 操作可能需要一段时间才能完成。如果需要等待该操作完成后才能向客户端发送响应,可能会造成不可接受的延迟。在这种情况下,请考虑将该操作设置为异步操作。返回 HTTP 状态代码 202(已接受),指示该请求已接受进行处理,但尚未完成。

应公开一个可返回异步请求状态的终结点,使客户端能够通过轮询状态终结点来监视状态。在 202 响应的 Location 标头中包含状态终结点的 URI。例如:

HTTP/1.1 202 Accepted
Location: /api/status/12345

如果客户端向此终结点发送 GET 请求,响应中应包含该请求的当前状态。(可选)响应中还可以包含预计完成时间,或者用于取消操作的链接

HTTP/1.1 200 OK
Content-Type: application/json
{
    "status":"In progress",
    "link": { "rel":"cancel", "method":"delete", "href":"/api/status/12345" }
}

如果异步操作创建了新资源,则该操作完成后,状态终结点应返回状态代码 303(查看其他)。在 303 响应中,包含一个 Location 标头用于提供新资源的 URI:

HTTP/1.1 303 See Other
Location: /api/orders/12345

有关详细信息,请参阅异步请求-回复模式

Sub-collection

有时,API 需要让客户跨子集执行 List/Search 操作。例如,“API 图书馆”有一组书架,每个书架都有一系列书籍,而客户希望在所有书架上搜索某一本书。在这种情况下,建议在子集合上使用标准 List,并为父集合指定通配符集合 ID "-"。对于“API 图书馆”示例,我们可以使用以下 REST API 请求:

GET https://library.googleapis.com/v1/shelves/-/books/{id}


注意:选择 "-" 而不是 "*" 的原因是为了避免需要进行 URL 转义。

Action

常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变的属性)
  • DELETE(DELETE):从服务器删除资源。

对于非标准的操作,以上动词无法无法满足需求,可以在资源上使用“操作”子集合。 动作基本上类似于RPC的消息,用于对资源执行特定操作。 “动作”子集合可以看作是一个命令队列,可以将新的动作发布到该命令队列中,然后由API执行。定义标准动词如下:

  1. batch:批量操作
  2. search:搜索操作
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
GET /zoos/-/action/batch  批量查询
POST /zoos/-/action/batch 批量更新
POST /zoos/-/action/search 搜索

其他

  • null 和不存在的属性使用相同的语义
required nullable {} {“example”:null}
true true ✗ No ✔ Yes
false true ✔ Yes ✔ Yes
true false ✗ No ✗ No
false false ✔ Yes ✗ No
  • 路径使用 中划线 - 代替 下划线 _

在搜索引擎中,把中划线当做空格处理,而下划线是被忽略的。使用中划线是对搜索引擎友好的写法

  • Example:
/shipment-orders/{shipment-order-id}
  • 范围
    表示范围的字段应该使用半开区间和命名惯例 [start_xxx, end_xxx),例如 [start_key, end_key)[start_time, end_time)。通常 C ++ STL 库和 Java 标准库会使用半开区间语义。API 应该避免使用其他表示范围的方式,例如 (index, count)[first, last]

总结

完成以上这些,也仅仅是达到REST Level 2,由于Level 3 对于API风格影响不大,暂不涉及。对 HATEOAS 感兴趣,可以参考 Github v3 版本的API。

参考链接

本文作者 : cyningsun

本文地址https://www.cyningsun.com/06-29-2020/how-to-write-restful-api.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!

# API Design

  1. 如何设计资源标识符?
  2. 如何设计 RPC 接口
  3. 如何选择合适的分布式ID生成方案?
目录
相关文章
|
10天前
|
缓存 API 网络架构
掌握现代API开发:GraphQL vs REST
【10月更文挑战第24天】本文深入探讨了现代API开发中两种主流技术——GraphQL和REST的设计理念、技术特点及实际开发中的对比分析。GraphQL通过声明式数据请求和强类型系统提供更高的灵活性和性能,而REST则以其无状态特性和成熟的生态系统见长。文章还讨论了两者在客户端-服务器交互、安全性和工具支持方面的优劣,帮助开发者根据项目需求做出明智选择。
|
2月前
|
JSON 中间件 API
开发REST API3-11
开发REST API3-11
|
2月前
|
JSON JavaScript API
编写REST API
编写REST API
55 2
|
1月前
|
Java API Maven
使用 Smart-doc 记录 Spring REST API
使用 Smart-doc 记录 Spring REST API
38 0
|
3月前
|
XML 安全 API
REST 和 SOAP API 有什么区别?
【8月更文挑战第31天】
161 0
|
3月前
|
JSON API 数据安全/隐私保护
哇塞!Django REST framework 太逆天啦!构建 API 服务从未如此轻松,你还不来试试?
【8月更文挑战第31天】Django REST framework(DRF)是基于Django框架的高效Web API开发工具,提供序列化、视图集、路由等功能,简化API构建流程。使用DRF可轻松实现数据的序列化与反序列化,并支持权限管理和认证机制以保障API安全。安装DRF只需通过`pip install djangorestframework`命令。要创建基本项目,先安装Django并创建新应用,定义模型、序列化器及视图集,最后配置路由。测试API时,可通过Postman发送HTTP请求验证功能。无论项目大小,DRF均能提供强大支持。
37 0
|
3月前
|
中间件 API 网络架构
Django后端架构开发:从匿名用户API节流到REST自定义认证
Django后端架构开发:从匿名用户API节流到REST自定义认证
37 0
|
4月前
|
JSON API 网络架构
gRPC 与 REST 的比较分析:哪种 API 适合您的开发需求?
gRPC, 由 Google 推出的开源远程过程调用(RPC)框架, 使两个应用程序间的方法调用变得简单,支持结构化数据的交换。通过采用 Protocol Buffers (Protobuf) ——一种与语言无关的接口定义语言,gRPC 体现了许多现代网络通信技术的优势
gRPC 与 REST 的比较分析:哪种 API 适合您的开发需求?
|
4月前
|
开发框架 Java API
Java中的REST API开发详解
Java中的REST API开发详解
|
4月前
|
开发框架 Java API
Java中的REST API开发详解
Java中的REST API开发详解