API设计
API设计
HTTP/1
REST原则
REST(representational state transfer 具象状态传输)
两个核心 | 释义 |
---|---|
RE | 表层,也叫做资源表现层、资源的表现形式、具象,例如 JSON、XML 都属于表现层 |
ST | 状态存于客户端需要传递到服务端 |
6个约束 | 释义 | |
---|---|---|
使用 C/S 架构 | 资源通过URI(Uniform Resource Identifier)统一资源标识符表示,URL(Uniform Resource Locator)统一资源定位符)定位符是URI的子集 例如,前后端分离,页面和服务不在同一服务器上运行 |
|
统一接口 | 例如,GET、POST、PUT、DELETE | |
无状态 | 服务端并不会保存有关客户的任何状态(session),也就是说要服务后端服务,就要带 token 过去 客户端通过JWT、OAuth维护状态 |
|
缓存 | GET一般缓存、POST不缓存 例如:服务端通过 token 缓存已登录过的用户信息,客户端请求会带一个 token 过来,后台服务通过带过来的 token 在缓存中取出用户信息 |
|
分层系统 | 例如, 一个父系统下有多个子模块,每个模块都是独立的服务 | |
按需代码 | 例如,服务端返回JS拓展客户端功能 |
RESTful API(C/S架构 CRUD)
RESTful API(符合REST原则的API)提供了一组设计原则和约束条件(不是标准)
应用场景:C/S架构
优点:URL简洁有层次,更易于实现缓存等机制
缺点:有些操作(sign_in)不好表示为资源、粒度不好把握(所有、单个、部分信息、整合信息)
实践:
SpringMVC
原生态的支持了 REST 风格的架构设计
所涉及到的注解:@RequestMapping
@PathVariable
@ResponseBody
请求
请求协议:使用 HTTP 协议,并利用 HTTP 方法(GET、POST、PUT、DELETE)来对资源执行不同的操作
接口风格:使用基于资源的接口风格
响应数据格式:常用 JSON 等轻量级数据格式(XML重)
非 Restful API URL | RESTful API URI | |
---|---|---|
根据用户id查询用户数据 | [GET] http://127.0.0.1/user/query/1 | [GET] http://127.0.0.1/user/1 |
新增用户 | [POST] http://127.0.0.1/user/save | [POST] http://127.0.0.1/user |
修改用户信息 | [POST] http://127.0.0.1/user/update | [PUT] http://127.0.0.1/user |
删除用户信息 | [GET/POST] http://127.0.0.1/user/delete | [DELETE] http://127.0.0.1/user |
总结:操作与资源定位分离
HTTP API 成功和错误响应格式
方案一:业务状态用 http code 表示(不建议)
1使用业务code在业务错误下是很有必要的,业务code表示业务状态、http code表示网络状态。即请求成功但是业务错误返回 {200, errcode, errmsg}
2客户端部分请求库将非200定义为异常需要try catch
方案二:同时使用 http code 和业务code(成功返回data,失败返回4/5XX)(推荐)
方案三:使用200 + 业务code(目前240616国内很多)
RESTful API:用 HTTP 功能
微软Azure API设计最佳实践
Azure REST API
RPC:把 HTTP 当成纯传输协议用
接口设计(不属于REST原则)
-
幂等性:是指对同一个操作的多次执行所产生的效果是相同的,不会因为重复提交而导致数据状态的改变。它确保了在进行数据操作时不会产生意外的副作用,从而保证了系统的稳定性和一致性。
分布式环境下客户端实现重试或消息补偿机制重复发送同一个请求,这时应使用乐观锁 -
统一响应(不推荐)
业务code | msg |
---|---|
0 | 服务器处理成功 |
1XXX | 参数异常 |
2XXX | 数据库处理异常 |
- 无状态
不用session
客户端存
后端统一存储
GraphQL(复杂数据类型)
应用场景:复杂类型数据(需要对后端数据整合,不然会获取不足或过度获取)
RPC
gRPC(微服务)
基于 HTTP2
优点:
Protocol Buffers 比 JSON 高效
支持双向流式传输
应用场景:分布式系统的微服务
浏览器没有暴露HTTP/2接口所以应用程序不能直接使用 gRPC