RESTful API设计标准

1. API的用户体验优先

将用户体验置于首位,API设计不仅要满足功能性需求,还要关注非功能性需求,如响应速度、交互体验、API文档的易读性等

2.资源导向
  • 资源为中心:RESTful API 应围绕资源(如用户、订单、文章、事件等)设计,每个资源都有一个唯一的URI,如/user/123表示特定用户的资源
  • API的资源粒度:精细把控API资源的粒度,既要避免资源过于细化导致调用复杂,也要防止资源过大导致的性能问题,找到最适合业务场景的平衡点

在API设计中,资源粒度指得是你定义API接口时,对业务对象划分的细致程度。

比如,如果你有一个用户管理的API,你可以设计成:

粗粒度:一个接口返回所有用户的信息

中粒度:一个接口返回单个用户的所有信息

细粒度:多个接口分别返回单个用户的基本信息、订单记录、活动参与情况等不同部分的信息

选择合适的资源粒度很重要,因为它直接影响到API的灵活性、可扩展性和性能。粒度过粗可能导致获取数据时冗杂信息多,粒度过细则可能会导致频繁调用接口,增加网络延迟和服务器负担。理想的粒度应该是既能满足业务需求,又能保持API易用且高效。
3. 统一接口

HTTP方法的使用:根据HTTP协议的语义,正确地使用不同的HTTP方法来执行CRUD操作

  • GET:用于获取资源或资源列表
  • POST:用于新建资源,常出现在集合资源的末端,如/users,附带资源数据在请求体中
  • PUT:用于替换整个资源,需提供完整的资源表示,URI指向的是要更新的具体资源
  • PATCH:用于部分更新资源,仅需提供要修改的属性
  • DELETE:用于删除指定资源
4. 无状态性

每个请求都包含处理请求所需的所有信息,服务器不需要存储会话状态。

客户端可以通过标准的认证机制(如OAuth、JWT)来维护状态。

5. 层级化结构

在更复杂的系统中,可能会倾向于提供能够让客户端通过多层关系进行导航的URI,如/customers/1/order/99/products,这是错误的做法

尽量保持URI相对简洁。一旦应用有了某个资源的引用,应能够使用该引用找到与该资源相关的项目。

如先通过/customers/1/order/99/products找到客户1的所有订单,然后再通过/orders/99/products找到该订单中的产品。

6. 超媒体作为引擎信息

API响应中包含链接和其他元数据(如链接关系、操作选项),帮助客户端发现和导航到其他相关资源。

JSON
{  
    "links": [  
        {  
            "rel": "self",  
            "href": "http://example.com/self",  
            "action": "GET",  
            "types": [  
                "application/hal+json"  
            ]  
        },  
        {  
            "rel": "next",  
            "href": "http://example.com/next",  
            "action": "GET",  
            "types": [  
                "application/json"  
            ]  
        },  
        {  
            "rel": "previous",  
            "href": "http://example.com/previous",  
            "action": "GET",  
            "types": [  
                "text/html"  
            ]  
        },  
        {  
            "rel": "profile",  
            "href": "http://example.com/schema",  
            "action": "GET",  
            "types": [  
                "application/schema+json"  
            ]  
        },  
        {  
            "rel": "item",  
            "href": "http://example.com/items/{id}",  
            "action": "GET",  
            "types": [  
                "application/vnd.collection+json"  
            ]  
        }  
    ]  
}
7. 版本管理

API版本管理可以有不同的策略,但常见做法是在URI或请求头中指明版本

HTTP
https://example.com/v2/cutomers/3
8. 错误处理

提供统一格式的错误响应,如使用HTTP状态码表示错误类型,并在响应中包含详细的错误信息

JSON
{
    "code": "A868",
    "message": "500 Internal Server Error"
}

每个业务应有统一的完整的错误编码 如:A868

9. 幂等性

对于同一请求多次发送应该产生相同的效果(除非资源状态本身已改变),这对于PUT、DELETE等操作尤其重要。

10. 内容协商

支持客户端 和服务器之间协商数据格式,如JSON、XML或其他内容类型,通过Content-Type和Accept头部来决定请求和响应的内容格式。

HTTP
POST https://ichistudio.cn HTTP/1.1
Accept:application/json; charset = utf-8

Content-Type: application/json; charset = utf-8
Content-Length:57
11. 过滤与排序

提供对资源列表的过滤与排序功能,通常通过查询参数实现

12. 分页与限制

当资源列表过长时,应提供分页功能,常见的做法是通过查询参数传递页码和每页数量

13. 字段选择

允许客户端指定需要返回的资源字段,减少不必要的数据传输,提升性能

14. 必要时提供客户端SDK
  • 简化开发流程:SDK充当了API与客户端应用程序之间的桥梁,通过预先封装好HTTP请求、响应处理、身份验证机制、错误处理等复杂的网络交互逻辑,降低了开发者直接调用API的难度和复杂性,提高了开发效率。
  • 增强易用性:SDK通常会提供与目标编程语言更为契合的API接口和方法,使得开发者能以更加自然和便捷的方式调用API,从而专注于业务逻辑的开发,而不是处理低层级的技术细节。
  • 标准化和一致性:SDK可以确保客户端与服务器间的交互遵循一致的标准和最佳实践,避免因开发者自行实现造成的不一致性问题,有利于保证API服务的安全性和稳定性
  • 提高用户体验:通过SDK可以实现诸如缓存、离线支持等功能,提升客户端应用的性能和用户体验,尤其是对于移动应用和弱网络环境下的表现尤为重要。
  • 快速迭代与支持:当后台API发生变化或新增功能时,通过提供更新的SDK版本,可以让客户更容易地进行升级和适应,避免因API变动而导致的大量代码重构工作
15. 测试与监控

设计API的同时应考虑到测试的便捷性,提供Swagger规范或类似的API描述文件可以帮助自动化测试。

同时,为API添加日志记录、性能监控等功能,以便后期维护和优化。

实现全面的API性能监控,包括但不限于响应时间、错误率、吞吐量等指标,以便及时发现并解决问题。

同时,建立详细的日志系统,记录所有API调用行为及其相关数据,这对于排查问题和审计追踪至关重要。

16. 向后兼容和升级政策

随着业务发展,API可能需要迭代更新。

在设计初期就要考虑如何在不影响现有客户端的情况下升级API,这可能涉及到版本控制、逐步弃用旧版本API及过渡策略等问题。

在实际的RESTful API设计中,向后兼容和升级策略可能包括:

  • 版本控制:就像手机系统会有1.0版、2.0版一样,API也可以加上版本号。当有重大更改时,可以发布一个新的API版本,老版本维持运行一段时间,让开发者逐渐迁移到新版API上。
  • 非破坏性变更:尽可能地在不改变原有接口行为的前提下进行升级,比如新增字段但不删除原有的字段,或者新增API路径而不是修改已有路径的行为。
  • 兼容模式:在新版本中暂时保留一些旧的行为模式,即使它们已经被优化或替换,直到大部分用户完成迁移。
17. 标准化约束

尽量遵循现有的网络标准最佳实践,例如RFC 723x系列HTTP规范,确保API的行为可预测且与其他系统兼容。

18. 速率限制

对于高负载的API,实施合理的速率限制策略,避免因恶意或过度的请求导致服务崩溃。

应在API响应中提供有关剩余配额的信息,便于客户端做出相应的调整。

19. 认证与授权

引入多种认证方式,如基本认证、OAuth、JWT等,根据场景选择合适方案。

授权方面,基于角色的访问控制(RBAC)或基于权限的访问控制(ABAC)可以帮助定义不同用户或客户端对资源的操作权限,认证和授权分开考虑。

20. 批量操作

对于批处理操作,提供API支持,允许一次调用执行多个相关的操作,降低客户端与服务器间的通信开销。

比如,一个电商应用,平常可能需要一次次发送请求去创建、更新或删除多个订单。

采用批量操作的话,就可以在一个API请求中包含多个订单的数据,一次性完成这些操作,这样能大大提高效率,减少网络传输的开销。

在RESTful API设计中,批量操作可能体现为一个特定的接口,接收一个包含多个资源数据的集合作为输入参数,然后统一进行相应的操作处理。

不过要注意的是,批量操作虽然高效,但设计时也需要考虑其复杂性和可能带来的风险,例如错误处理和事务一致性等问题。

21. 缓存策略

对于那些不会频繁变动且计算成本较高的资源,适当引入缓存机制可以显著提升API性能。

通过设置合适的HTTP缓存头(如Cache-Control、ETag等),让客户端和服务端协同实现高效的缓存管理。

22. 安全性强化

加密通信:强制要求HTTPS连接,确保数据传输过程中的隐私和完整性

防止跨站请求伪造(CSRF)攻击:对于需要用户身份验证的API,采取措施防范这类攻击,比如添加CSRF令牌。

23. 健康检查与可用性

提供一个专门的健康检查API端点,用于快速验证服务是否正常运行,这对于自动化的运维和故障恢复十分有用

24. API分层与网关

在复杂的系统架构中,可能需要引入API网关来实现统一的安全策略、路由管理、限流熔断等功能,并且可以根据不同的层级划分内部服务接口和对外公开的API。

25. 回滚策略

在API发布新版本后,如果出现严重问题,应有一套快速回滚至先前稳定版本的预案,确保业务连续性。

26. API的可发现性

通过目录服务或者API门户提供API清单,使开发者能够轻松查找和了解所有可用的API资源,从而提高API的利用率和推广效果。

DEV环境或QA环境可以使用Swagger UI的方式生成清单、生产环境不允许,系统安全性无法保障。

27. API性能优化

通过数据库索引优化、缓存策略、CDN加速、API Gateway的负载均衡等方式提升API的性能表现,为用户提供更快捷的服务。

28. API的实时统计分析

实施API调用实时统计和数据分析,洞察API的使用趋势、热点路径、潜在瓶颈等,为优化决策提供数据支持。

29. API的自动化测试

编写单元测试、集成测试和契约测试,确保API的功能正确性,随着API的演变,保持测试覆盖率并及时更新测试用例。

30. API的文档更新同步

当API发生变化时,确保对应的API文档、示例代码和SDK等资料能及时更新,避免开发者依据过时文档编写代码导致的问题。

31. API的合规性考虑

在设计API时要考虑法律法规的要求,例如GDPR对于数据隐私的规定,确保API的设计和使用符合相关法规标准。

32. API的扩展性设计

考虑未来的业务拓展和技术变革,设计API时预留一定的扩展性,例如通过URL路径参数或查询参数灵活控制资源范围,或采用模块化设计以便后续增加新的功能组件。

订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
滚动至顶部