开发一定要知道的 REST API URI 7 条设计规则
通常情况下,程序员都会接触 Web 开发,那就不得不提到 RESTAPI URL 的设计规则。
一个好的 URL 可以让其他研发一眼会明确知道功能,那就不得不说一下 RESTAPI。
良好的 URI 设计的一般原则:
- 不要使用查询参数来改变状态
- 不要使用大小写混合的路径。小写是最好的
- 不要在 URI 中使用特定于实现的扩展名(.php、.py、.pl 等)
- 保持路径段短
- 使用查询参数对资源进行子选择;即分页,搜索查询
- 将应该在 HTTP 标头或正文中的内容移出 URI
- 对所有资源使用复数名称
HTTP 方法选择的一般原则:
- 永远不要使用 GET 来改变状态
- 除非您要更新整个资源,否则不要使用 PUT
- 不要使用 PUT 除非您也可以合法地在同一个 URI 上执行 GET
- 不要使用 POST 来检索长期存在的信息或可能合理缓存的信息
- 不要使用 PUT 执行非幂等操作
- 如有疑问,请优先使用 POST 而不是 PUT
- 每当您必须做一些感觉像 RPC 的事情时,请务必使用 POST
- 使用 DELETE 优先于 POST 来删除资源
使用 HTTP 设计 Web 服务的一般原则:
- 不要将元数据放在应位于标头中的响应正文中
- 不要将元数据放在单独的资源中,除非包含它会产生大量开销
- 请使用适当的状态码
201 Created
创建资源后;资源在发送响应时必须存在202 Accepted
成功执行操作或异步创建资源后400 Bad Request
当有人对明显虚假的数据进行操作时;对于您的应用程序,这可能是一个验证错误;通常为未捕获的异常保留 500401 Unauthorized
当有人在没有提供必要的Authorization
标头的情况下访问您的 API 或其中的凭据Authorization
无效时;如果您不希望通过Authorization
标头获得凭据,请不要使用此响应代码。403 Forbidden
当有人以可能是恶意的方式或未经授权的方式访问您的 API 时405 Method Not Allowed
当有人在他们应该使用 PUT 时使用 POST 等413 Request Entity Too Large
当有人试图向您发送一个无法接受的大文件时。- 尽可能使用缓存标头
ETag
当您可以轻松地将资源减少为哈希值时,标头很好Last-Modified
应该向您表明,保留资源更新时间的时间戳是个好主意Cache-Control
并且Expires
应该被赋予合理的价值- 尽你所能尊重请求中的缓存标头 (
If-None-Modified
,If-Modified-Since
)
REST API 前置知识
一、资源
是谁的表现层?这里省略了主语,其实指的是资源(Resources)的表现层。
所谓"资源",就是网络上的信息。可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的事物,好比于 Unix/Linux 的基本哲学之一:一切皆是文件。
URI (Uniform Resource Identifier,统一资源定位符):每一个资源的地址或独一无二的识别符,要获取这个资源,访问它的 URI就可以。
日常中所说的"上网",就是与互联网上一系列的"资源"进行互动,调用它的 URI。
二、表现层
"资源"具体呈现现出来的形式,叫做它的"表现层"(Representation),如:文本可以用 txt、html、json 等多种格式进行展现。
URI 只代表资源的实体,不代表它的形式。严格地说,有些网址最后的 .html 后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴
我们应该在 HTTP 协议报头中用 Accept 字段(请求报头,客户端希望接受的数据类型)指定,这才是对"表现层"的描述。
三、状态转化
通过网络去访问一个系统,就代表了客户端和服务器的一个互动过程,在这个过程中,势必涉及到数据和状态的变化。
由于 HTTP 是无状态协议,资源的状态都保存在服务器端。因此客户****端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer),而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
在 HTTP 协议里面,定义了四种操作方式的动词:GET、POST、PUT、DELETE,它们分别对应四种基本操作:
-
GET:获取****资源
-
POST:创建、更新****资源
-
PUT:更新****资源
-
DELETE:删除****资源
最佳原则
-
在 URI 设计时考虑名词,而不是动词。
RESTful API 是基于名词的——你正在对事物的端点执行操作。另一方面,RPC/SOAP 端点是动词——它们是用来做某事的东西。 -
尊重变更管理流程。避免对人们正在使用的现有端点引入中断更改。
3.保持一致。这意味着使用 HTTP 状态代码、通用 API 结构、公认的最佳实践等。
4.从一开始就考虑版本控制。
5.使用 Swagger 等工具的API 文档。
-
处理 API 中的错误需要仔细规划。这里的 REST API 最佳实践是每次都以相同的格式返回错误消息。
-
始终对结果进行分页
-
将您的 JSON 响应分为元和数据字段
-
使用查询字符串来操作数据
查询字符串应该用于对数据进行排序、搜索和过滤。您也可以分页,正如我们之前谈到的,但查询字符串通常更容易浏览
REST API URL 详细规则
1、URI 中不应包含结尾的正斜杠(/)
这是要遵循的最重要的规则之一,因为 URI 路径中的最后一个字符,正斜杠(/)不会增加语义值,并且可能引起混乱。REST API 不应包含斜线,也不应将其包含在它们提供给客户端的链接中。
许多 Web 组件和框架将同等对待以下两个URI:
api.canvas.com/shapes/
api.canvas.com/shapes
但是,URI 中的每个字符都会计入资源的唯一标识。
两个不同的URI映射到两个不同的资源。如果URI不同,则资源也不同,反之亦然。因此,REST API 必须生成并传递干净的 URI ,并且不应容忍任何客户端错误地识别资源的尝试。
更多宽容的 API 可以将客户端重定向到URI,而不会在末尾加反斜杠(它们也可能会返回 301 –“永久移动”,用于重新定位资源”)。
2、必须使用正斜杠分隔符(/)表示层次关系。
URI的路径部分使用正斜杠(/)字符表示资源之间的层次关系。例如: http://api.canvas.com/shapes/polygons/quadrilaterals/squares
3、应使用连字符(-)来提高URI的可读性
为了使您的URI易于人们扫描和解释,请使用连字符(-)来提高长路径段中名称的可读性。在英语中使用空格或连字符的任何地方,都应在 URI 中使用连字符。
例如:http://api.example.com/blogs/guy-levin/posts/this-is-my-first-post
4、URI中不应使用下划线 _
文本查看器应用程序(浏览器,编辑器等)通常在 URI 下划线,以提供可单击的可视提示。根据应用程序的字体,下划线 _ 字符可能会被此下划线部分掩盖或完全隐藏。
为避免这种混淆,请使用连字符(-)代替下划线。
5、在 URI 路径中应首选小写字母
方便时,URI 路径中最好使用小写字母,因为大写字母有时会引起问题。RFC 3986 将 URI 定义为区分大小写,但方案和主机组件除外。
例如:
1)api.example.com/my-folder/m…
2)API.EXAMPLE.COM/my-folder/m…
上面的 URI 很好。URI格式规范(RFC 3986)认为此 URI 与 URI1相同。
3)http://api.example.com/My-Folder/my-doc
该 URI 与 URI1和 URI2不同,这可能导致不必要的混淆。
6、文件扩展名不应包含在 URI 中
在 Web 上,句点(。)字符通常用于分隔URI的文件名和扩展名部分。REST API 不应在 URI 中包含人工文件扩展名,以指示消息的实体主体的格式。相反,它们应该依靠通过 Content-Type 标头传达的媒体类型来确定如何处理正文内容。
api.college.com/students/32…
api.college.com/students/32…
文件扩展名不应用于指示格式首选项。
应该鼓励 REST API 客户端利用 HTTP 提供的格式选择机制,即 Accept request 标头。
为了实现简单的链接和调试,REST API 可以通过查询参数支持媒体类型选择。
7、端点名称应为单数还是复数?
保持简单规则在此处适用。尽管内部语法专家会告诉您使用复数形式描述资源的单个实例是错误的,但务实的答案是保持URI格式的一致性,并始终使用复数形式。
不必处理不规则复数形式(person/people, goose/geese),使API消费者的生活更美好,是对 API 提供商实现(如最现代化的框架通过 controller 处理 /students 和 /students/3248234 很容易)。
但是您如何处理关系?如果关系只能存在于另一个资源中,则RESTful原则将提供有用的指导。让我们来看一个例子。一个学生有许多课程。这些课程在逻辑上映射到 /students
端点,如下所示:
http://api.college.com/students/3248234/courses
-检索 ID 为 3248234 的学生学习的所有课程的列表。
http://api.college.com/students/3248234/courses/physics
-检索 ID 为 3248234 的学生的课程中的物理。