什么才是好的 REST API?
如今,任何具备基本编程技能的人都可以构建 API。FastAPI 等框架提供了直观的界面,并且文档齐全,让构建 API 变得非常简单。但是,如何才能交付和维护其他开发人员喜爱的、始终按预期运行且扩展性良好的强大 REST API?
本文提供了 REST API 最佳实践的概述,涵盖:
- API 设计
- 开放API
- 验证
- 速率限制
- 异步处理
- 监控
我不会在每个部分中讲得太详细,但是我会为那些有兴趣深入了解的人提供有关该主题的更多资源的链接。
API 设计:遵循最佳实践
好的 API 具有经过深思熟虑且合乎逻辑的端点设计,以易于使用的方式返回数据,并在出现错误时提供详细的反馈。
目前已有设计 API 端点的最佳实践。这些通常包括:
- 在 URI 中对资源集合使用复数名词,例如
/v1/posts/123
- 避免在端点 URI 中使用动词,而应使用适当的 HTTP 方法
- 保持 URI 中的所有字符小写,使用连字符分隔单词
- 逻辑地嵌套端点以显示关系。例如,博客文章上的评论应该是
/v1/posts/{postId}/comments/{commentId}
。 - 在端点 URI 中包含一个版本,例如
/v1/posts
,以便将来进行更新而不会破坏现有客户端 - 确保所有 API 端点的命名约定、响应格式和行为一致
- 在响应中使用适当的 HTTP 状态代码,例如,
201 Created
如果创建了新资源或403 Forbidden
出现授权错误 - 允许用户使用查询参数对数据集进行过滤、排序和分页,并避免返回过大的 API 响应
更多资源:
- REST API 设计的最佳实践- Stack Overflow 博客
- RESTful API 指南- Zalando
- API 设计标准-澳大利亚政府
OpenAPI:自动生成文档和 SDK
好的 API 具有完整的 OpenAPI 规范,可作为 API 提供者与消费者之间的契约。它还用于创建全面的文档和 SDK。
许多 Web 框架都支持从 API 代码库中的端点定义自动生成 OpenAPI 规范,无论是开箱即用还是通过第三方库。您可以使用注释来添加其他详细信息,例如描述和示例。通过与 Web 框架紧密集成来保持单一事实来源有助于使规范与代码库保持最新状态并进行版本控制。
有许多工具使用 OpenAPI 规范来:
- 生成交互式文档
- 生成各种语言的客户端库/SDK
- 生成模拟服务器以进行测试
- 根据规范自动测试你的 API 端点
- 和更多 …
更多资源:
- 什么是 OpenAPI? - OpenAPI 计划
- OpenAPI 规范说明- OpenAPI 计划
- OpenAPI.Tools -你不会讨厌的 API
推荐工具:
- Redoc:生成 API 文档
- Mintlify:生成 API 文档
- openapi-ts:为 TypeScript 生成 API 客户端
- openapi-python-client:为 Python 生成 API 客户端
验证
好的 API 会一丝不苟地验证用户输入,并在收到无效输入时提供详细且结构化的错误消息。
作为一项基本任务,许多 Web 框架都很好地支持输入验证。例如,FastAPI 为此使用了 pydantic,并自动生成包含结构良好的验证错误详细信息的响应(见下面的示例)。
{
"detail": [
{
"type": "missing",
"loc": ["body", "name"],
"msg": "Field required",
"input": { ... }
}
]
}
创建验证规则时,请考虑以下标准:
- 类型:确保输入具有正确的数据类型。
- 长度:检查输入是否具有预期的长度并定义上限(例如禁止极长的字符串输入,或包含数百万个元素的数组)。
- 格式:根据预期模式检查字符串输入以确保其格式正确(例如日期)。
- 范围:确保数值在可接受的范围内。
- 业务逻辑:根据您自己的业务规则检查输入(最后执行此操作)。
输入验证应尽早进行,并在处理无效请求时快速失败。使用 4xx 范围内的适当 HTTP 状态代码来处理验证错误(例如400 Bad Request
)。
一些 Web 框架还可以对 API 响应执行验证(例如,带有 pydantic 的 FastAPI),从而保证返回的数据始终具有正确的结构和类型。或者,API 端点应由自动化测试覆盖,以确保在任何情况下响应数据的格式都正确(根据 API 的规范)。
更多资源:
- 输入验证备忘单- OWASP
速率限制
好的 API 采用速率限制来防止过载并确保所有客户端的服务质量。
速率限制可以在堆栈的不同级别实现,包括网络级别、Web 服务器、应用程序代码或这些的组合。
作为第一层保护,大多数 Web 服务器都可以轻松配置为按 IP 地址限制请求速率。为了获得更大的灵活性和更好的控制,您可能需要在应用层实现(额外的)速率限制逻辑。例如,您可以根据用户的定价层应用动态限制。
当由于速率限制而拒绝请求时,最好使用429 Too Many Requests
响应状态代码并包含标头,以便Retry-After
向客户端提供反馈,以便他们能够优雅地处理速率限制。
确保您的 API 文档清楚地说明了速率限制规则并描述了所使用的速率限制标头。
更多资源:
- API 速率限制 - 您需要了解的一切- HubSpot 博客
- API 速率限制:终极指南- Kinsta 知识库
异步处理
好的 API 使用任务队列和工作系统在后台执行较长时间运行的任务,并避免长时间保持客户端连接打开。
这通常涉及从客户端接受任务,将其添加到任务队列,然后立即发送响应以确认已收到任务并正在处理。202 Accepted
响应状态代码通常用于此场景。
这种方法可以改善用户体验,并有助于防止超时,因为客户端无需等待响应。它还允许服务器同时处理多个请求,并在处理长时间运行的任务时保持响应。
API 还应为客户端提供一种方法来检查其任务的状态并获取结果(如果适用)。这可以实现为客户端可以定期轮询的单独端点。
更多资源:
- 异步请求-答复模式- Microsoft Learn
监控
良好的 API 会受到主动监控,以确保其一致的可用性、可靠性和性能。
有了监控工具,您就可以快速检测问题并做出响应,最好是在问题影响用户之前。它还可以帮助您了解 API 的使用方式,并使您能够做出数据驱动的产品和工程决策。
监测至少应涵盖以下关键方面:
- 流量:请求数(每分钟)
- 错误:由于客户端或服务器错误导致请求失败
- 响应时间/延迟:API 端点返回响应需要多长时间
- 正常运行时间:API 是否可供消费者使用
更多资源:
- 您应该实施的 API 监控的 4 个方面- Apitally 博客
推荐工具:
- Apitally:易于使用的 Python 和 Node.js API 监控