Rest API 设计

淡淡的烟草味﹌ 2022-05-14 12:53 456阅读 0赞

【问题】

在以前的项目经验中,接口请求都是GET或者POST方式;接口定义都是以动词开头,比如,按名称查询某用户信息,都是写成queryByUserName;接口不管对内还是对外,都是一套,也没有所谓的版本,等等。这一系列问题,都是Restful风格中不允许出现的,所以在提供对外接口前,先学习了下,如何设计Restful风格API,从而让第三方使用我们的接口第一感觉就是专业和规范。

【安全与幂等】

每一种HTTP请求方法都可以从安全性和幂等性两方面考虑,要定义严谨的REST统一接口,就需要真正理解HTTP方法的安全性和幂等性。

安全性是指对外系统对该接口的访问,不会使服务器端资源的状态发生变化;幂等性是指外系统对同一REST接口的多次访问,得到的资源状态是相同的。

【HTTP请求】

  • GET

只读操作的请求,用于读取资源,它既是安全的,也是幂等的。但可能因为不良的API设计,使得违背其特性。

标准的命名方式是单数的操作以资源名称命名,批量的操作以资源名称的复数名称命名。比如同步订单可用order和orders。

  • PUT

是一种写操作的HTTP请求,用于更新或添加资源。PUT方法是幂等的,即多次插入或更新同一份数据,在服务器端对资源状态所产生的改变是相同的。但PUT方法是不安全的,有写动作的HTTP方法都是不安全的。

  • POST

用于写数据,其特性是既不幂等也不安全。由于请求会改变服务器端资源状态,因此是不安全的;由于每次请求对服务器端的资源状态的改变并不是相同的,所以它不是幂等的。

  • DELETE

该方法是幂等的,即多次删除同一份数据(通常请求中传递的参数是数据的主键值),在服务器端产生的改变是相同的。

执行删除的资源方法,其返回值可以定义为void,即没有任何返回值。因为删除的前提是对该资源信息已经充分了解,没有必要再将其从服务器上传递回来。

【请求比较】

在创建某个和更新某个资源的时候,可能我们比较迷茫的是何时使用PUT方法,何时使用POST方法。

  • 更新资源

由于使用同一份数据向服务器请求更新某一资源,得到的结果应该总是相同的,因此,对于更新操作,使用PUT方法是没有问题的。

  • 创建资源

创建操作每次得到的结果是不同的,因为服务器端的业务逻辑通常要求数据的主键字段是不同的,要么是业务上自增的一个逻辑值,要么是数据库的主键自增,因此,相同的数据每一次提交到服务器端,都会为数据添加一个新的主键值,也就是创建一个主键值不同的新资源。所以创建操作通常应该设计为POST方法的API。

【使用示例】




































请求方法 请求示例 请求说明
GET /orders 查询所有订单
POST /orders 创建一个订单
GET /orders/ID 获取某个订单的信息
PUT /orders/ID 更新某个指定订单的信息
DELETE /orders/ID 删除某个订单

【设计指导】

(一)使用名词而不是动词



























资源(Resource) 读(GET) 创建(POST) 修改(PUT) 删除(DELETE)
/orders 返回orders集合 创建新的资源 批量更新orders 删除所有的orders
/orders/100 返回特定的order 该方法不允许(405) 更新一个指定的资源 删除指定的资源

而不要使用:
/getAllOrders
/createNewOrder
/deleteAllOrders

(二)使用复数名词

不要混淆名词单数和复数,为了保持简单,只对所有资源使用复数。

/orders 而不是 /order
/users 而不是 /user
/cars 而不是 /car

(三)Get方法和查询参数不应该涉及状态改变

使用PUT, POST 和DELETE 方法 而不是 GET 方法来改变状态

(四)为集合提供过滤 排序 选择和分页等功能

  • Filtering过滤:

使用唯一的查询参数进行过滤:

GET /orders?compID=15 返回某个供应商的订单
GET /orders?orderMoney>1000 返回订单金额大于1000的orders集合

  • Sorting排序:

允许针对多个字段排序

GET /orders?sort=-createTime,+orderMoney

这是返回根据创建时间降序和金额升序排列的order集合

  • Field selection

移动端能够显示其中一些字段,它们其实不需要一个资源的所有字段,给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。

GET /orders?fields=createTime,orderMoney,id,buyerAddress

  • Paging分页

使用 limit 和offset.实现分页,缺省limit=20 和offset=0;

(五)版本化API

使得API版本变得强制性,不要发布无版本的API,使用简单数字,避免小数点如2.5.

一般在Url后面使用?v

/orders/api/v1

(六) 使用Http状态码处理错误

如果你的API没有错误处理是很难的,只是返回500和出错堆栈不一定有用

Http状态码提供70个出错,我们只要使用10个左右:

  • 200 – OK – 一切正常
  • 201 – OK – 新的资源已经成功创建
  • 204 – OK – 资源已经成功擅长
  • 304 – Not Modified – 客户端使用缓存数据
  • 400 – Bad Request – 请求无效,需要附加细节解释如 “JSON无效”
  • 401 – Unauthorized – 请求需要用户验证
  • 403 – Forbidden – 服务器已经理解了请求,但是拒绝服务或这种请求的访问是不允许的。
  • 404 – Not found – 没有发现该资源
  • 422 – Unprocessable Entity – 只有服务器不能处理实体时使用,比如图像不能被格式化,或者重要字段丢失。
  • 500 – Internal Server Error – API开发者应该避免这种错误。

发表评论

表情:
评论列表 (有 0 条评论,456人围观)

还没有评论,来说两句吧...

相关阅读

    相关 RESTful API 设计指南

    网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。 因此,必须有一种统一的机制,方便不同

    相关 RESTful API 设计指南

    网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。 因此,必须有一种统一的机制,方便不同的前端设备

    相关 Rest API 设计

    【问题】 在以前的项目经验中,接口请求都是GET或者POST方式;接口定义都是以动词开头,比如,按名称查询某用户信息,都是写成queryByUserName;接口不管对内还是

    相关 restful api接口设计

    技术由来: 互联网早期,页面请求和并发量不高,且移动端未盛行时对接口要求不高,使用动态页面(jsp)就能满足绝大多数的使用需求。但是随着互联网和移动设备的发展,人们对We