ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

REST API 设计常见问题

2022-01-15 17:32:24  阅读:118  来源: 互联网

标签:200 code REST API error 常见问题 order


服务间的通讯方式,经历了IPC/RPC, CORBA, SOAP 等远程协议后, REST API 成为了事实标准。但是由于一些思维惯性,在实践中没有抓住 REST 理念的的精髓。主要有以下的一些问题:

1. 使用动词或动名词设计 URL

 以一个订单的API 设计为例, 对一创建订单的 URL 写为:

/xxx_domain/create_order

这里使用了create_order 。 这里延用了函数的命名规则, 将 API 对应到了函数的调用。事实上 REST 理念以资源为中心设计,每一个  URL 应该对应一类资源,这里是订单 order 。 通过 HTTP Method  表达对资源的增删改查等操作。一个创建订单的REST API 应该设计为:

POST /xxx_domain/order 

这里 POST 表达创建, order 表达资源。HTTP Method 和 URL 两者构成 API 的整体。

REST API 通常使用的 HTTP Method:

  • GET 查询/获取 资源,该 API 应该是幂等的,是一个只读操作,不改变资源的状态。
  • POST 创建 新的资源,该 API 不保证是幂等的,重复调用可能创建重复的资源。服务端和客户端自行协商如何控测和避免创建重复的资源。
  • PUT 更新 资源状态, 该 API 应保证操作是幂等的,重复调用多次的效果和调用一次的效果相同。 
  • PATCH 更新 资源状态, 对 PUT 操作对比,PATCH 不保证是幂等的。通常应该优先选择 PUT 操作。
  • DELETE 删除资源,该 API 应该是幂等的,调用多次和调用一次效果相同。

 

2. 只使用 GET 操作,只返回 200 状态码

在项目中一个非常普遍的现象是只使用 GET 动词 (也有只使用 POST的)。 通常给出的原因有如下几种:

1. GET 操作更安全。因为对外部来说 GET 看起来是一个只读操作。 

2. 容易统一标准,前端容易处理。

3. 早期的互联网接入提供商会拦截非 200 状态码,返回广告页面。

在只返回 200 状态码的情况下,对请求响应返回体中包含如下三项:

{

   “error_code”: "100",

   "error_message": "",

   "data": { "xx": "..." }

}

客户端首先检查返回状态码是 200, 否则表求网络请求超时了。然后获取响应体,检查 “errror_code” 是否达成功,这里的“error_code”通常是各业务部门自定,没有统一的标准。如果不成功,显示 “error_message”;成功则提取“data”,走正常的业务逻辑。

try {

    HttpResponse response = httpClient.createOrder();

    if ( response.statusCode == 200 ) {

      if ( response.body.errorCode == 100 ) {

            Order order = unmarshal(response.body.data);

         } else {

            print( response.body.errorCode, response.body.errorMessage )

        }

    }  else {

      // ... 

    }

} catch ( Exception e ) {

print( "timeout");

}

按照 REST 理念 HTTP Status Code 应该直接表达 API 操作是否成功, 并使用 HTTP status code 的标准语义, 比如:

  • 200 操作成功
  • 400 客户端错误(在 REST API里指参数错误)
  • 401 用户未认证(登录)
  • 403 用户未授权
  • 404 资源不存在
  • 500 服务内部错误
  • 503 上游服务错误

对于响应返回体,如果操作成功,应该直接返回业务对象

{

“xx”: "..."

}

如果操作不成功,应该返回错误信息:

{

  "error_code" : "1000",

  "error_message": "xxxxxxxxx"

}

这样表达表面看起来响应体有两种,前端要分别处理。实际上前端代码更简洁,因为不管是前端 javascript http 函数,还是后端 OpenFeign 等框架,绝大部分都使用了异常机制,当 http code 不是 2xx, 就抛异常了。所以前端只需要写如下类似的代码(伪代码)

try {

 Order order = httpClient.createOrder();

} catch ( BizException e ) {

print( e.errorCode() , e.errorMessage()); 

}

 

3. 返回 API 职责以外的信息

对于 API 职责划分不清,比如创建订单成功的返回体是这样的。

{

   "error_code": 1001,

    "error_message": "缺货待补",

    "data" : {"orderId": 123}

}

业务开发定义 创建成功是 100, 创建部分成但明有附加信息 是 1001。 创建失败是 200, 。。。

应该将API 的职责划分清晳明确,创建订单只完成创建订单的事项。订单状态等划分到其它的 API。 

 4. URL 中使用下划线"_"分隔 

比如前文的 create_order, 事实上 URL 中推荐用减号"-"分隔。 

标签:200,code,REST,API,error,常见问题,order
来源: https://www.cnblogs.com/log4jerry/p/15807509.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有