RESTful API 最佳实践

简介: RESTful API 最佳实践

RESTful是目前最流行的 API 设计规范,用于 Web 数据接口的设计。


它的大原则容易把握,但是细节不容易做对。本文总结 RESTful 的设计细节,介绍如何设计出易于理解和使用的 API。


一、URL 设计



1.1 动词 + 宾语


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


动词通常就是五种 HTTP 方法,对应 CRUD 操作。


GET:读取(Read)
POST:新建(Create)
PUT:更新(Update)
PATCH:更新(Update),通常是部分更新
DELETE:删除(Delete)
根据 HTTP 规范,动词一律大写。


1.2 动词的覆盖


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


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


POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT


上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST。


1.3 宾语必须是名词


宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词,不能是动词。比如,/articles这个 URL 就是正确的,而下面的 URL 不是名词,所以都是错误的。


/getAllCars
/createNewCar
/deleteAllRedCars


1.4 复数 URL


既然 URL 是名词,那么应该使用复数,还是单数?


这没有统一的规定,但是常见的操作是读取一个集合,比如GET /articles(读取所有文章),这里明显应该是复数。


为了统一起见,建议都使用复数 URL,比如GET /articles/2要好于GET /article/2。


1.5 避免多级 URL


常见的情况是,资源需要多级分类,因此很容易写出多级的 URL,比如获取某个作者的某一类文章。


GET /authors/12/categories/2


这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。


更好的做法是,除了第一级,其他级别都用查询字符串表达。


GET /authors/12?categories=2


下面是另一个例子,查询已发布的文章。你可能会设计成下面的 URL。


GET /articles/published


查询字符串的写法明显更好。


GET /articles?published=true


二、状态码



2.1 状态码必须精确


客户端的每一次请求,服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分。


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


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


这五大类总共包含100多种状态码,覆盖了绝大部分可能遇到的情况。每一种状态码都有标准的(或者约定的)解释,客户端只需查看状态码,就可以判断出发生了什么情况,所以服务器应该返回尽可能精确的状态码。


API 不需要1xx状态码,下面介绍其他四类状态码的精确含义。


2.2 2xx 状态码


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


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


上面代码中,POST返回201状态码,表示生成了新的资源;DELETE返回204状态码,表示资源已经不存在。


此外,202 Accepted状态码表示服务器已经收到请求,但还未进行处理,会在未来再处理,通常用于异步操作。下面是一个例子。


HTTP/1.1 202 Accepted
{
  "task": {
    "href": "/api/company/job-management/jobs/2130040",
    "id": "2130040"
  }
}


2.3 3xx 状态码


API 用不到301状态码(永久重定向)和302状态码(暂时重定向,307也是这个含义),因为它们可以由应用级别返回,浏览器会直接跳转,API 级别可以不考虑这两种情况。


API 用到的3xx状态码,主要是303 See Other,表示参考另一个 URL。它与302和307的含义一样,也是"暂时重定向",区别在于302和307用于GET请求,而303用于POST、PUT和DELETE请求。收到303以后,浏览器不会自动跳转,而会让用户自己决定下一步怎么办。下面是一个例子。


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


2.4 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.5 5xx 状态码


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


500 Internal Server Error:客户端请求有效,服务器处理时发生了意外。


503 Service Unavailable:服务器无法处理请求,一般用于网站维护状态。


三、服务器回应



3.1 不要返回纯本文


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


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


GET /orders/2 HTTP/1.1 
Accept: application/json

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


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


HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "failure",
  "data": {
    "error": "Expected at least two items in list."
  }
}


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


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


HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "error": "Invalid payoad.",
  "detail": {
     "surname": "This field is required."
  }
}


3.3 提供链接


API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS。


举例来说,GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL。


{
  ...
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  ...
}


上面的回应中,挑一个 URL 访问,又可以得到别的 URL。对于用户来说,不需要记住 URL 设计,只要从 api.github.com 一步步查找就可以了。


HATEOAS 的格式没有统一规定,上面例子中,GitHub 将它们与其他属性放在一起。更好的做法应该是,将相关链接与其他属性分开。


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



目录
相关文章
|
1月前
|
弹性计算 监控 安全
API稳定安全最佳实践:用阿里云SDK为业务保驾护航
阿里云智能集团高级技术专家赵建强和曹佩杰介绍了API稳定安全最佳实践,涵盖业务上云真实案例、集成开发最佳实践、配额管理和共担模型四部分。通过分析企业在不同阶段遇到的问题,如签名报错、异常处理不严谨、扩容失败等,提出了解决方案和工具,确保API调用的安全性和稳定性。特别强调了SDK的使用、无AK方案、自动刷新机制以及配额中心的作用,帮助用户构建更稳定、安全的服务,提升运维效率。最终介绍了集成开发共担模型,旨在通过最佳实践和平台工具,保障业务的稳定与安全,推动行业创新与发展。
|
2月前
|
存储 安全 Java
Spring Boot 编写 API 的 10条最佳实践
本文总结了 10 个编写 Spring Boot API 的最佳实践,包括 RESTful API 设计原则、注解使用、依赖注入、异常处理、数据传输对象(DTO)建模、安全措施、版本控制、文档生成、测试策略以及监控和日志记录。每个实践都配有详细的编码示例和解释,帮助开发者像专业人士一样构建高质量的 API。
106 9
|
2月前
|
监控 数据管理 测试技术
API接口自动化测试深度解析与最佳实践指南
本文详细介绍了API接口自动化测试的重要性、核心概念及实施步骤,强调了从明确测试目标、选择合适工具、编写高质量测试用例到构建稳定测试环境、执行自动化测试、分析测试结果、回归测试及集成CI/CD流程的全过程,旨在为开发者提供一套全面的技术指南,确保API的高质量与稳定性。
|
2月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
71 12
|
3月前
|
XML JSON 缓存
深入理解RESTful API设计原则与实践
在现代软件开发中,构建高效、可扩展的应用程序接口(API)是至关重要的。本文旨在探讨RESTful API的核心设计理念,包括其基于HTTP协议的特性,以及如何在实际应用中遵循这些原则来优化API设计。我们将通过具体示例和最佳实践,展示如何创建易于理解、维护且性能优良的RESTful服务,从而提升前后端分离架构下的开发效率和用户体验。
|
3月前
|
JSON 缓存 测试技术
构建高效RESTful API的后端实践指南####
本文将深入探讨如何设计并实现一个高效、可扩展且易于维护的RESTful API。不同于传统的摘要概述,本节将直接以行动指南的形式,列出构建RESTful API时必须遵循的核心原则与最佳实践,旨在为开发者提供一套直接可行的实施框架,快速提升API设计与开发能力。 ####
|
3月前
|
JSON API 开发者
深入理解RESTful API设计原则
在数字化时代,API已成为连接不同软件应用的桥梁。本文旨在探讨RESTful API设计的基本原则和最佳实践,帮助开发者构建高效、可扩展的网络服务接口。通过解析REST架构风格的核心概念,我们将了解如何设计易于理解和使用的API,同时保证其性能和安全性。
|
3月前
|
存储 缓存 API
深入理解RESTful API设计原则
在现代软件开发中,RESTful API已成为前后端分离架构下不可或缺的通信桥梁。本文旨在探讨RESTful API的核心设计原则,包括资源导向、无状态、统一接口、以及可缓存性等,并通过实例解析如何在实际应用中遵循这些原则来构建高效、可维护的API接口。我们将深入分析每个原则背后的设计理念,提供最佳实践指导,帮助开发者优化API设计,提升系统整体性能和用户体验。
60 0
|
3月前
|
安全 测试技术 API
构建高效RESTful API:后端开发的艺术与实践####
在现代软件开发的浩瀚星空中,RESTful API如同一座桥梁,连接着前端世界的绚丽多彩与后端逻辑的深邃复杂。本文旨在探讨如何精心打造一款既高效又易于维护的RESTful API,通过深入浅出的方式,剖析其设计原则、实现技巧及最佳实践,为后端开发者提供一份实用的指南。我们不深入晦涩的理论,只聚焦于那些能够即刻提升API品质与开发效率的关键点,让你的API在众多服务中脱颖而出。 ####
45 0
|
3月前
|
监控 安全 API
深入浅出:构建高效RESTful API的最佳实践
在数字化时代,API已成为连接不同软件和服务的桥梁。本文将带你深入了解如何设计和维护一个高效、可扩展且安全的RESTful API。我们将从基础概念出发,逐步深入到高级技巧,让你能够掌握创建优质API的关键要素。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的指导和启示。让我们一起探索API设计的奥秘,打造出色的后端服务吧!

热门文章

最新文章