Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

REST API 设计之 —— HTTP 方法

  一提到 RESTful 的方法,很多人脑子里就会蹦出 POST 创建、PUT 修改、DELETE 删除,这种观点。我不知道这个观点到底从什么地方传起的,但只要是懂英语的人都知道,上面这段描述除了 DELETE,其它两个都不对。为什么 POST 是创建?为什么 PUT 是修改?
  RESTful 是让大家更加语义化,而不是机械式地使用这些方法。我猜可能是某些培训机构的老师怕学生听不懂,直接不负责任地说 POST 创建、PUT 修改。在某些情况下,它们是对的,但不仅限于此。< br/>   比如 PUT 是「放置」的意思,将某个东西放在某个位置。在 HTTP 中就是将实体放在 URL 上。如果 URL 上已经有别的东西就将它替换掉,这便是所谓的「修改」。但是如果 URL 上本身没有东西呢?按照 PUT 的语义,服务器可以执行创建的操作,只要操作的客户有提供足够的鉴权信息。
  有时候会看到一些很诡异的 API 设计,比如更新列表的某个记录会出现这样的东西: PUT /list body: { "id":id, ... }   这是一个不伦不类的东西嘛。PUT 一个 list,如果参数是一个数组还可以理解, PUT 一个对象到一个 list 是几个意思?这个对象还奇奇怪怪地带着 id,完全说不上是 RESTful。而且如果说它是 SOA,那干嘛要用到 PUT 方法?正确的应该是
PUT /list/:id body: { ... }   另外,顺便说一下,对于同一个资源,GET 方法得到的实体应该和 PUT 上传是一致的。也就是说 GET 的时候实体中同样不应该带 id。如果非要说 id 从哪里拿到,那应该是其它接口,比如直接 GET /list 之类的。对于资源的部分修改或其它高级修改方式应该用 PATCH 方法。
  说 POST 是创建也是不对的。POST 是把一堆信息抛给服务器处理而已,它可以做任何事情。本来 POST 就是被设计来提交表单这样的事务型操作的。所以 POST 可以理解为执行服务器的一个事务。通常我们不会把创建的权限开给 PUT,因为会造成安全性问题。所以会使用 POST 来创建,于是 POST 就被和「创建」划上等号了。实际上 POST 能做任何事情,只要是其它方法无法满足的事情都可以交给 POST,作为一个事务处理。
  比如有一个下单的接口,应该怎么设计?如果把下单这件事情认为是「往订单表插入一条记录」而设计成 POST /orders,那就错了。下单是个很复杂的操作,它可能会创建多个资源,比如创建一个发货申请给商家、创建一个订单历史给用户等,并且还会修改很多资源,比如减少库存、对用户扣款等。它是一个典型的事务。如果只是给一个列表类型的资源 POST 创建一个记录就造成这么大的影响,那就一点都不 RESTful 了。
  正确的处理方式应该是将「下单」这个动作设计为一个事务的接口,使用 POST 方法调用这个事务,并把一些必要的参数传过去。所以 POST 这个方法可以视为是 REST API 中的 RPC,可以做任何事情。因为 HTTP 方法毕竟是有限的,无法完成所有事情,总是需要有这样的万金油。但我们还是得把所有可以通过其它方法实现的东西都用其它方法实现,避免让整套 API 降级为 SOA。
  其它方法比如 DELETE 之类的语义就比较强,一般不会搞错。但也别强行使用 DELETE,比如取消订单这样的操作同样是事务,DELETE 就不适合。
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^