序
应用程序编程接口 (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 的设计应考虑可测试性,以便轻松进行集成测试、负载测试和回归测试,以确保可靠性和稳健性。
具象状态传输 (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 更加直观且易于理解。
POST /users - 创建一个新用户
GET /users/{id} - 通过ID检索用户
PUT /users/{id} - 更新现有用户
DELETE /users/{id} - 删除用户
这种设计关注“用户”资源,并通过标准 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 方法对用户配置文件资源执行不同的操作。
200 OK:请求成功,响应中包含请求的数据。
201 Created:新资源创建成功。
204 No Content: 请求成功,但没有返回响应体。
400 Bad Request:请求格式错误或包含无效参数。
401 Unauthorized:请求需要身份验证或提供的凭据无效。
403 Forbidden: 客户端没有权限访问所请求的资源。
404 Not Found: 未找到请求的资源。
500 Internal Server Error: 服务器发生意外错误。
通过一致地使用适当的状态代码,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的更改或更新,而不会破坏依赖于先前版本的客户端应用。
基于偏移量的分页:指定偏移量(起始索引)和限制(项目数)以检索特定结果页。
基于游标的分页:使用不透明游标或标记来跟踪结果集中的位置并获取下一页。
过滤允许客户端通过指定条件或参数来缩小结果范围,仅检索他们需要的数据。这可以通过查询参数或请求标头来实现。
示例:用于检索分页和过滤的产品列表的 API 端点可能如下所示:
GET /products?page=2&pageSize=10&category=computer&priceRange=100-500
在此示例中,API 通过指定page和pageSize参数以及按category和进行过滤来支持分页priceRange。
服务器端缓存:API 服务器缓存经常访问的数据或响应,以减少昂贵的数据库查询或计算的需要。
客户端缓存:客户端可以在本地缓存 API 响应,从而减少发送到服务器的请求数量。
缓存代理:专用缓存层或反向代理可用于缓存 API 响应并将其直接提供给客户端。
在实现缓存时,必须考虑缓存失效机制、缓存过期策略和缓存一致性,以确保数据的一致性和新鲜度。
示例:假设有一个检索产品列表的 API 节点:
get/product
你可以通过将产品列表存储在内存、 Redis 或 Memcached 等缓存层中来实现服务器端缓存。对同一端点的后续请求可以从缓存中得到服务,从而减少数据库的负载,并有效缩短响应时间。
此外,你可以在 API 响应中设置适当的缓存标头(例如Cache-Control、ETag)以启用客户端缓存和缓存验证。
日志记录:实施全面的日志记录机制来捕获有关 API 请求、响应、错误和其他重要事件的相关信息。日志对于调试、监视和审计目的非常宝贵。
示例:考虑用于创建新用户的 API 节点:
post/user
如果请求负载缺少必填字段或包含无效数据,API 应返回400 Bad Request带有结构化错误响应的状态代码,例如:
{
"error" : "InvalidRequestBody" ,
"message" : "请求正文缺少必填字段或包含无效数据。" ,
"detail_info" : [
{
"field" : "Email" ,
"error" : "InvalidEmailFormat"
} ,
{
"field" : "Password" ,
"error" : "密码太短"
}
]
}
此外,API 应记录有关请求的相关信息,包括请求负载、标头以及处理过程中发生的任何异常或错误。
身份验证:客户端必须通过向端点提供有效凭据(例如用户名和密码)来获取访问令牌/auth/token。
授权:每个 API 请求必须在标头中包含访问令牌Authorization。API 服务器验证令牌并检查客户端是否具有执行请求的操作所需的权限。
# 身份验证POST /auth/token
{
"username" : "user@example.com" ,
"password" : "securepassword"
}
# 授权 API 请求
GET /orders
授权:Bearer
通过实施适当的身份验证和授权机制,可以确保只有授权的客户端才能访问 API 并执行特定操作。
API端点及其请求/响应格式
认证和授权机制
错误处理和响应代码
使用示例和代码示例
版本控制和迁移指南
速率限制和节流策略
此外,以流行的编程语言提供软件开发套件(SDK)和客户端库可以进一步增强开发人员的体验并提高生产力。
示例:考虑使用 Swagger 等文档工具来记录你的 API,并为开发人员提供交互式界面来探索和测试 API 节点。
# swagger.yaml
swagger: '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
本文为 @ 万能的大雄 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。