RESTful 最佳实践

简介: RESTful 最佳实践

RESTful 是目前最流行的 API 规范,适用于 Web 接口规范的设计。让接口易读,且含义清晰。本文将介绍如何设计易于理解和使用的 API,并且借助 Docker api 的实践说明。

URL 设计

1.1 动词 + 宾语

它的核心思想就是客户端发出的数据操作指令都是「动词 + 宾语」的结构,比如 GET /articles这个命令,GET是动词,/articles是宾语。

动词通常来说就是五种 HTTP 方法,对应我们业务接口的 CRUD 操作。而宾语就是我们要操作的资源,可以理解成面向资源设计。我们所关注的数据就是资源。

  • GET: 读取资源
  • POST:新建资源
  • PUT:更新资源
  • PATCH:资源部分数据更新
  • DELETE:删除资源

正确的例子

  • 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:删除某个指定动物园的指定动物

1.2 动词的覆盖

有些客户端只能使用GET和POST这两种方法。服务器必须接受 POST 模拟其他三个方法(PUT、PATCH、DELETE)。

这时,客户端发出的 HTTP 请求,要加上 X-HTTP-Method-Override 属性,告诉服务器应该使用哪一个动词,覆盖 POST 方法。

1.3 宾语必须是名词

就是 API 的url ,是 HTTP 动词作用的对象,所以应该是名词。例如 /books 这个 URL 就是正确的,而下面的 URL 不是名词,都是错误的写法。

错误示范:

GET /getAllUsers?name=jl
POST /createUser
POST /deleteUSer

1.4 复数名词

URL 是名词,那么是使用复数还是单数?

没有统一的规定,但是我们通常操作的数据多数是一个集合,比如 GET /books ,所以我们就使用复数。

统一规范,建议都使用复数 URL, 比如 获取 id = 2 的书 GET /books/2 要好于 GET /book/2

1.5 避免出现多级 URL

有时候我们要操作的资源可能是有多个层级,因此很容易写多级 URL,比如获取某个作者某种分类的文章。

GET /authors/2/categories/2 获取作者ID = 2 分类 = 2 的文章

这种 URL 不利于拓展,语义 也不清晰。

更好的方式就是 除了第一级,其他级别都是通过查询字符串表达。

正确方式: GET /authors/12?categories=2

查询已发布的文章

错误 写法: GET /artichels/published

正确写法: GET /artichels?published=true

过滤信息(Filtering)

状态码如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。

下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo-id=ID 的含义是相同的。推荐后者,避免出现多级URL。

2.1 状态码必须精确

客户端的请求,服务求都必须响应,包含 HTTP 状态码和数据。

HTTP 状态码就是一个三位数,分成五个类别。

  • 1xx:相关信息
  • 2xx:操作成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

2.2 2xx 状态码

200状态码表示操作成功,但是不同的方法可以返回更精确的状态码。

  • GET: 200 OK
  • POST: 201 Created
  • PUT: 200 OK
  • PATCH: 200 OK
  • DELETE: 204 No Content

2.3 4xx 状态码

4xx状态码表示客户端错误,主要有下面几种。

  • 400 Bad Request:服务器不理解客户端的请求,未做任何处理。
  • 401 Unauthorized:用户未提供身份验证凭据,或者没有通过身份验证。
  • 403 Forbidden:用户通过了身份验证,但是不具有访问资源所需的权限。
  • 404 Not Found:所请求的资源不存在,或不可用。
  • 405 Method Not Allowed:用户已经通过身份验证,但是所用的 HTTP 方法不在他的权限之内。
  • 410 Gone:所请求的资源已从这个地址转移,不再可用。
  • 415 Unsupported Media Type:客户端要求的返回格式不支持。比如,API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。
  • 422 Unprocessable Entity :客户端上传的附件无法处理,导致请求失败。
  • 429 Too Many Requests:客户端的请求次数超过限额。

2.4 5xx 状态码

5xx状态码表示服务端错误。一般来说,API 不会向用户透露服务器的详细信息,所以只要两个状态码就够了。

  • 500 Internal Server Error:客户端请求有效,服务器处理时发生了意外。
  • 503 Service Unavailable:服务器无法处理请求,一般用于网站维护状态。

服务器响应

3.1 不要返回纯文本

API 返回的数据格式,不应该是纯文本,而应该是一个 JSON 对象,因为这样才能返回标准的结构化数据。所以,服务器回应的 HTTP 头的 Content-Type 属性要设为 application/json 。

客户端请求时,也要明确告诉服务器,可以接受 JSON 格式,即请求的 HTTP 头的ACCEPT 属性也要设成 application/json。下面是一个例子。

3.2 发生错误的时候,不要返回 200 状态码

有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样。

错误例子:

HTTP/1.1 200 OK
ConteNTP-Type: application/json
{
"status": "fail",
"msg": "错误"
}

上面代码中,解析数据体以后,才能得知操作失败。

这张做法实际上取消了状态码,这是完全不可取的。正确的做法是,状态码反映发生的错误,具体的错误信息放在数据体里面返回。下面是一个例子。

正确方式:

HTTP/1.1 400 Bad Request
ConteNTP-Type: application/json
{
"status": "fail",
"msg": "错误"
}

docker RESTful 规范解析

接下来我们分析 docker api 对于 restful 的使用,助于我们在实际工作中合理设计。

docker 文档 url :https://docs.docker.com/engine/api/v1.19/

4.1 GET 获取容器列表

GET /v1.19/containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1

通过 all=1&before=8dfafdbc3a40&size=1 过滤容器数据

4.2 GET 获取指定ID或者名字容器

GET /containers/(id or name)/json

GET /v1.19/containers/4fa6e0f0c678/json HTTP/1.1

4.3 GET 获取某个容器的进程

GET /v1.19/containers/4fa6e0f0c678/top HTTP/1.1

假如想过滤进程等可以通过查询字符串实现

GET /v1.19/containers/4fa6e0f0c678/top?ps_args=aux HTTP/1.1

返回的数据

HTTP/1.1 200 OK
Content-Type: application/json
{
  "Titles" : [
    "USER","PID","%CPU","%MEM","VSZ","RSS","TTY","STAT","START","TIME","COMMAND"
  ]
  "Processes" : [
    [
      "root","13642","0.0","0.1","18172","3184","pts/0","Ss","17:03","0:00","/bin/bash"
    ],
    [
      "root","13895","0.0","0.0","4348","692","pts/0","S+","17:15","0:00","sleep 10"
    ]
  ],
}

4.4 POST 创建容器

POST /containers/create

POST /v1.19/containers/create HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
      "Hostname": "",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": true,
      "AttachStderr": true,
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [
              "FOO=bar",
              "BAZ=quux"
      ],
      "Cmd": [
              "date"
      ],
      "Entrypoint": null,
      "Image": "ubuntu",
      "Labels": {
              "com.example.vendor": "Acme",
              "com.example.license": "GPL",
              "com.example.version": "1.0"
      },
      "Volumes": {
        "/volumes/data": {}
      }
  }

4.5 DELETE 删除容器

根据容器 id 删除一个容器,v是请求是否删除 容器 volumes

DELETE /v1.19/containers/16253994b7c4?v=1 HTTP/1.1

Query parameters:

  • v – 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false.
  • force - 1/True/true or 0/False/false, Kill then remove the container. Default false.
  • link - 1/True/true or 0/False/false, Remove the specified link associated to the container. Default false.


相关文章
|
1月前
|
JSON 算法 安全
探索RESTful API设计的最佳实践
【9月更文挑战第2天】在数字化时代的浪潮中,后端开发如同搭建一座桥梁,连接着用户与数据的无限可能。本文将深入探讨如何打造高效、可维护的RESTful API,从资源命名到状态码的巧妙运用,每一个细节都隐藏着提升用户体验的智慧。你将学会如何在浩瀚的代码海洋中,用简洁明了的设计原则,引领用户安全抵达数据的彼岸。让我们一起启航,探索API设计的奥秘,让后端开发成为艺术与科学的完美结合。
|
3月前
|
机器学习/深度学习 API iOS开发
探索iOS开发中的SwiftUI框架深入理解RESTful API设计原则与最佳实践
【7月更文挑战第30天】本文深入探讨了SwiftUI框架在iOS开发中的应用,分析了其对用户界面构建的简化方法及性能优化。通过比较传统UI构建方式与SwiftUI的差异,揭示了SwiftUI如何提高开发效率和用户体验。文章还讨论了SwiftUI在实际项目中的集成策略,并展望了其未来的发展方向。 【7月更文挑战第30天】在数字时代的浪潮中,RESTful API如同一座桥梁,连接着不同的软件系统。本文将探讨RESTful API的核心设计原则,揭示其背后的哲学思想,并通过实例分析展示如何将这些原则应用于实际开发中。我们将从资源定位、接口一致性到HTTP方法的恰当使用,逐一剖析,旨在为开发者提供
52 1
|
21天前
|
JSON 前端开发 API
打造高效后端:RESTful API 设计的最佳实践
【9月更文挑战第14天】在数字化时代,后端开发是构建强大、灵活和可维护应用程序的基石。本文将深入探讨如何设计高效的RESTful API,包括清晰的资源定义、合理的HTTP方法使用、URL结构规划、状态码的准确返回以及数据格式的设计。通过这些实践,开发者能够创建出既符合行业标准又易于维护和扩展的API,为前端提供强大的数据支持,确保整个应用的稳定性和性能。
157 74
|
12天前
|
API 网络架构 UED
构建RESTful API的最佳实践
【8月更文挑战第54天】在数字化时代,RESTful API已成为连接不同软件系统、提供数据服务的关键桥梁。本文将深入探讨如何构建高效、可维护的RESTful API,涵盖设计原则、安全策略和性能优化等关键方面。通过具体代码示例,我们将一步步展示如何实现一个简洁、直观且功能强大的API。无论你是新手还是有经验的开发者,这篇文章都将为你提供宝贵的指导和启示。
63 33
|
2天前
|
API 开发者 UED
构建高效RESTful API的最佳实践
【9月更文挑战第33天】在数字化时代,后端开发不仅仅是关于代码的编写。它是一场架构艺术的演绎,是性能与可维护性之间的舞蹈。本文将带你深入理解RESTful API设计的精髓,探索如何通过最佳实践提升API的效率和可用性,最终实现后端服务的优雅蜕变。我们将从基础原则出发,逐步揭示高效API设计背后的哲学,并以实际代码示例为路标,指引你走向更优的后端开发之路。
|
9天前
|
缓存 监控 测试技术
深入理解RESTful API设计原则与最佳实践
【9月更文挑战第26天】在数字化时代,API(应用程序编程接口)已成为连接不同软件和服务的桥梁。本文将深入浅出地介绍RESTful API的设计哲学、六大约束条件以及如何将这些原则应用到实际开发中,以实现高效、可维护和易于扩展的后端服务。通过具体实例,我们将探索如何避免常见设计陷阱,确保API设计的优雅与实用性并存。无论你是API设计的新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的指导和启示。
|
10天前
|
缓存 前端开发 API
深入浅出:RESTful API设计的最佳实践
【9月更文挑战第24天】在数字化浪潮中,API作为连接不同软件组件的桥梁,其设计质量直接影响到系统的可维护性、扩展性及用户体验。本文将通过浅显易懂的语言,结合生动的比喻和实例,带领读者深入理解RESTful API设计的核心原则与最佳实践,旨在帮助开发者构建更加健壮、灵活且用户友好的后端服务。
|
14天前
|
API
构建高效RESTful API的最佳实践
【9月更文挑战第21天】在数字化时代,API已成为软件应用间沟通的桥梁。本文将探讨如何设计和维护一个高效的RESTful API,确保它不仅能够快速响应,同时也易于扩展和维护。我们将通过实际的代码示例来揭示这些最佳实践背后的逻辑和原理,帮助你构建一个既稳定又灵活的后端服务。
|
2月前
|
SQL 安全 API
数字堡垒之下:网络安全漏洞、加密技术与安全意识的博弈探索RESTful API设计的最佳实践
【8月更文挑战第27天】在数字化浪潮中,网络安全成为守护个人隐私与企业资产的关键防线。本文深入探讨了网络漏洞的成因与影响,分析了加密技术如何为数据保驾护航,并强调了提升公众的安全意识对于构建坚固的信息防御系统的重要性。文章旨在为读者提供一场思维的盛宴,启发更多关于如何在日益复杂的网络世界中保护自己的思考。
|
2月前
|
XML JSON API
RESTful API设计最佳实践:构建高效、可扩展的接口
【8月更文挑战第17天】RESTful API设计是一个涉及多方面因素的复杂过程。通过遵循上述最佳实践,开发者可以构建出更加高效、可扩展、易于维护的API。然而,值得注意的是,最佳实践并非一成不变,随着技术的发展和业务需求的变化,可能需要不断调整和优化API设计。因此,保持对新技术和最佳实践的关注,是成为一名优秀API设计师的关键。
下一篇
无影云桌面