17611538698
webmaster@21cto.com

Restful API设计最佳实践

架构 0 119 2024-04-03 11:52:40

图片

应用程序编程接口 (API) 已经成为现代级软件开发不可或缺的一部分,它使不同的系统和应用程序能够无缝地通信与交换数据。

随着互连和分布式系统的需求不断增长,API 的设计变得越来越重要。设计良好的 API 可以显着提高开发人员的工作效率、应用程序的可扩展性和整体系统的可维护性。

在这篇文章中,我们将从基础知识到最佳实践探索 API 设计,涵盖每个开发者都应该了解的基本概念、原则与指南。

什么是 API


在深入研究 API 设计之前,了解 API 是什么及其用途是至关重要的。 


图片API 是一组规则、协议和工具,用于定义软件组件如何相互交互。它充当中间层,允许不同的应用程序或服务进行通信和共享数据、功能或资源。


API 可以根据其架构、通信协议和用例分为各种类型。一些常见的 API 包括:


  • Web API:这些 API 是在使用 HTTP 或 HTTPS 等标准协议通过互联网时使用。RESTful API 和 GraphQL API 是 Web API 的流行示例。

  • 库或框架 API:这些 API 通常与软件库或框架捆绑在一起,并提供对其功能和特性的访问。

  • 操作系统 API:这些 API 由操作系统提供,以促进与系统资源(例如文件系统、网络或硬件组件)的交互。

  • 数据库 API:这些 API 使应用程序能够与数据库交互、执行查询以及管理数据存储和检索。


不论哪种类型,API 在现代软件架构中实现互操作性、模块化和集成方面都发挥着至关重要的作用。

API设计原则


设计有效的 API 需要遵守某些基本原则,以帮助确保一致性、可用性和可维护性。以下就是一些我们需要考虑的原则总结:


  • 简单性:API 的设计应考虑简单性,使其易于理解和使用。避免不必要的复杂性并努力实现整净直观的界面。

  • 一致性:一致性是 API 设计的关键。在整个 API 中保持一致的命名约定、结构和行为,以增强开发人员体验,并减少混乱。

  • 关注点分离:API 应该有明确的边界和职责,分离与数据、业务逻辑和表示相关的关注点。

  • 向后兼容性:在引入 API 的更改或新版本时,必须保持向后兼容性,以防止破坏现有的客户端应用程序。

  • 版本控制:实施版本控制策略以有效管理 API 更改,并允许客户按照自己的节奏迁移到新版本。

  • 安全性:API 通常处理敏感数据和操作,因此安全性成为关键考虑因素。实施适当的身份验证、授权和加密机制以防范潜在威胁。

  • 文档:记录良好的 API 对于开发人员了解如何使用它们并将其集成到应用程序中至关重要。应提供清晰、全面的文档,包括示例和使用场景。

  • 可扩展性:API 的设计应考虑可扩展性,考虑负载平衡、缓存和水平扩展等因素,以应对不断增长的需求和流量。

  • 可测试性:API 的设计应考虑可测试性,以便轻松进行集成测试、负载测试和回归测试,以确保可靠性和稳健性。


API 设计最佳实践


虽然遵守上述原则至关重要,但有一些最佳实践可以进一步提高 API 设计的质量和有效性。让我们详细探讨其中一些最佳实践:


1. RESTful API设计


具象状态传输 (REST) 已成为设计 Web API 广泛采用的架构风格。RESTful API 利用 HTTP 协议及其方法(GET、POST、PUT、DELETE)对资源执行操作。

通过遵循 RESTful 原则,API 变得更具可扩展性、可维护性并且易于开发人员理解。

示例,我们使用 RESTful API 来管理博客文章。如下:

  • GET /posts - 检索所有博客文章的列表

  • GET /posts/{id} - 通过 ID 检索特定博客文章

  • POST /posts - 创建新博客文章

  • PUT /posts/{id} - 更新现有的博客文章

  • DELETE /posts/{id} - 删除博客文章


在此示例中,API 遵循 RESTful 约定,使用 HTTP 方法对“posts”资源执行 CRUD(创建、读取、更新、删除)操作。描述性 URL 和标准 HTTP 方法的使用使 API 更加直观且易于理解。

2. 面向资源的设计


API 应该围绕它们公开的资源而非它们执行的操作来设计。这种面向资源的方法与 RESTful 架构保持一致,并促进更直观、更有组织的 API 结构。


示例:面向资源的设计不会设计动词端点的 API,比如像/createUser如/updateUser、/deleteUser之类,而要变成如下:


  • POST /users - 创建一个新用户

  • GET /users/{id} - 通过ID检索用户

  • PUT /users/{id} - 更新现有用户

  • DELETE /users/{id} - 删除用户


这种设计关注“用户”资源,并通过标准 HTTP 方法公开操作,使 API 更加一致且更易于理解。

3. 正确使用HTTP方法


HTTP 方法应在整个 API 中正确且一致地使用。每个方法都有一个应该有特定语义:


  • GET:检索资源的表示。GET 请求应该是安全且幂等的(多个相同的请求应该与单个请求具有相同的效果)。

  • POST:创建新资源或执行非幂等操作。

  • PUT:更新现有资源或创建新资源(如果不存在)。PUT 请求应该是幂等的。

  • DELETE:删除资源。

  • PATCH:部分更新资源。


示例:让我们思考一个用于管理用户配置文件的 API:

  • GET /users/{id}/profile - 检索用户的个人资料

  • POST /users/{id}/profile - 创建或更新用户的个人资料(非幂等)

  • PUT /users/{id}/profile - 更新用户的个人资料(幂等)

  • PATCH /users/{id}/profile - 部分更新用户的个人资料


在此示例中,遵循每个方法的语义,使用适当的 HTTP 方法对用户配置文件资源执行不同的操作。

4. 使用正确的状态代码


HTTP 状态代码提供了一种标准化的方式来传达 API 请求的结果。正确使用状态代码可以改善整体开发人员体验,并更轻松地处理客户端应用程序中的不同场景。


示例:以下是一些常见的状态代码及其在 API 响应中的用法:


  • 200 OK:请求成功,响应中包含请求的数据。

  • 201 Created:新资源创建成功。

  • 204 No Content: 请求成功,但没有返回响应体。

  • 400 Bad Request:请求格式错误或包含无效参数。

  • 401 Unauthorized:请求需要身份验证或提供的凭据无效。

  • 403 Forbidden: 客户端没有权限访问所请求的资源。

  • 404 Not Found: 未找到请求的资源。

  • 500 Internal Server Error: 服务器发生意外错误。


通过一致地使用适当的状态代码,API 可以提供更有意义和可操作的响应,使客户更轻松地处理不同的场景。

5. 版本控制


随着 API 的发展以及新功能或更改的引入,版本控制对于保持向后兼容性并允许客户按照自己的节奏迁移到新版本变得至关重要。


对 API 进行版本控制有多种方法,包括:


  • URL 版本控制:在 API URL 中包含版本号,例如/v1/users, /v2/users。

  • 标头版本控制:使用自定义 HTTP 标头来指定 API 版本,例如Accept-Version: v1.0

  • 查询参数版本控制:包含版本作为查询参数,例如/users?version=v1。


示例:使用 URL 版本控制,用于管理用户的 API 端点可能如下所示:

  • GET /v1/users- 检索用户列表(version 1)

  • POST /v2/users- 创建新用户(version 2)

  • PUT /v1/users/{id}- 更新现有用户(version 1)


通过对 API 进行版本控制,你可以引入API的更改或更新,而不会破坏依赖于先前版本的客户端应用。

6. 分页和过滤


许多 API 需要处理大型数据集,因此必须提供分页和过滤机制来管理返回的数据量并提高性能与可扩展性。


分页允许将大型结果集分割成更小的、可管理的块,从而减少服务器和客户端的负载。常见的分页技术包括:


  • 基于偏移量的分页:指定偏移量(起始索引)和限制(项目数)以检索特定结果页。

  • 基于游标的分页:使用不透明游标或标记来跟踪结果集中的位置并获取下一页。


过滤允许客户端通过指定条件或参数来缩小结果范围,仅检索他们需要的数据。这可以通过查询参数或请求标头来实现。

示例:用于检索分页和过滤的产品列表的 API 端点可能如下所示:

GET /products?page=2&pageSize=10&category=computer&priceRange=100-500

在此示例中,API 通过指定page和pageSize参数以及按category和进行过滤来支持分页priceRange。

7. 缓存


缓存可以通过减少服务器负载和减少响应时间来显着提高 API 的性能和可扩展性。可以采用不同的缓存策略,包括:


  • 服务器端缓存:API 服务器缓存经常访问的数据或响应,以减少昂贵的数据库查询或计算的需要。

  • 客户端缓存:客户端可以在本地缓存 API 响应,从而减少发送到服务器的请求数量。

  • 缓存代理:专用缓存层或反向代理可用于缓存 API 响应并将其直接提供给客户端。


在实现缓存时,必须考虑缓存失效机制、缓存过期策略和缓存一致性,以确保数据的一致性和新鲜度。

示例:假设有一个检索产品列表的 API 节点:

get/product

你可以通过将产品列表存储在内存、 Redis 或 Memcached 等缓存层中来实现服务器端缓存。对同一端点的后续请求可以从缓存中得到服务,从而减少数据库的负载,并有效缩短响应时间。

此外,你可以在 API 响应中设置适当的缓存标头(例如Cache-Control、ETag)以启用客户端缓存和缓存验证。

8. 错误处理和日志记录


正确的错误处理和日志记录对于维护 API 的可靠性和可维护性至关重要。精心设计的错误处理机制有助于向客户端提供有意义且可操作的错误消息,而全面的日志记录则有助于调试与故障排除。


错误处理:每当发生错误时,API 应返回适当的 HTTP 状态代码和错误消息。错误响应应该是结构化且一致的,为客户端提供足够的信息来优雅地处理错误。

日志记录:实施全面的日志记录机制来捕获有关 API 请求、响应、错误和其他重要事件的相关信息。日志对于调试、监视和审计目的非常宝贵。

示例:考虑用于创建新用户的 API 节点:

post/user

如果请求负载缺少必填字段或包含无效数据,API 应返回400 Bad Request带有结构化错误响应的状态代码,例如:

{   "error" :  "InvalidRequestBody" ,   "message" :  "请求正文缺少必填字段或包含无效数据。" ,   "detail_info" :  [     {       "field" :  "Email" ,       "error" :  "InvalidEmailFormat"     } ,     {       "field" :  "Password" ,       "error" :  "密码太短"     }   ] }



此外,API 应记录有关请求的相关信息,包括请求负载、标头以及处理过程中发生的任何异常或错误。

9. 认证与授权


大多数 API 处理敏感数据和操作,因此身份验证和授权成为 API 设计的关键方面。实施适当的身份验证和授权机制可确保只有授权的客户端才能访问 API 并执行特定操作。


身份验证是验证客户端或用户身份的过程,通常通过用户名、密码、API 密钥或 JSON Web 令牌 (JWT) 等凭据进行验证。


授权是确定经过身份验证的客户端或用户是否具有访问或执行 API 内某些操作的必要权限的过程。


示例:假设你有一个需要身份验证和授权的电子商务 API。可以执行以下操作:


  • 身份验证:客户端必须通过向端点提供有效凭据(例如用户名和密码)来获取访问令牌/auth/token。

  • 授权:每个 API 请求必须在标头中包含访问令牌Authorization。API 服务器验证令牌并检查客户端是否具有执行请求的操作所需的权限。

# 身份验证POST /auth/token {   "username" : "user@example.com" ,   "password" : "securepassword" } 
# 授权 API 请求GET /orders授权:Bearer

通过实施适当的身份验证和授权机制,可以确保只有授权的客户端才能访问 API 并执行特定操作。

10. 文档和开发人员经验


记录完善且非常注重开发人员体验的 API 可以显着提高 API 的采用率和可用性。清晰而全面的文档,包括 Swagger 或 Postman 等交互式文档工具,可以让开发人员更轻松地理解你的 API, 并将其顺利集成到他们的应用程序中。


API开发文档应包括以下详细信息:


  • API端点及其请求/响应格式

  • 认证和授权机制

  • 错误处理和响应代码

  • 使用示例和代码示例

  • 版本控制和迁移指南

  • 速率限制和节流策略


此外,以流行的编程语言提供软件开发套件(SDK)和客户端库可以进一步增强开发人员的体验并提高生产力。

示例:考虑使用 Swagger 等文档工具来记录你的 API,并为开发人员提供交互式界面来探索和测试 API 节点。

# swagger.yamlswagger: '2.0'info:  title: Blog API  version: 1.0.0
paths: /posts: get: summary: Retrieve a list of blog posts responses: '200': description: Successful response schema: type: array items: $ref: '#/definitions/Post'
definitions: Post: type: object properties: id: type: integer title: type: string content: type: string

结论

设计有效的 API 既是一门艺术,也是一门科学。

通过遵循本文中概述的原则和最佳实践,各位朋友可以创建直观、可扩展、可维护且易于使用的 API。请记住,API 设计是一个迭代过程,不断寻求开发者和利益相关者的反馈,有助于随着时间的推移完善和改进我们的 API。

随着技术的发展和新的架构模式和范例的出现,必须跟上最新趋势并相应地调整你的 API 设计实践。采用最佳实践并遵守行业标准将确保你的 API 保持可靠、高效且对开发人员友好,从而实现各种系统和应用程序之间的无缝集成和通信。

作者:金宝

参考:

https://medium.com/@techsuneel99/api-design-from-basics-to-best-practices-da47c63aaf70

评论