请问,我这样理解 restful 对不对?

2015-10-02 04:08:11 +08:00
 legendlee
最近设计了两个小型的前后端交互 api 接口系统,参考了 restful 的标准。但是我读的材料可能不够多,对 rest 理解的有点模糊,想让大家纠正一下。

目前而言,我理解的 rest 就是两句话: url 里面不允许出现任何动词,只能用来表示寻址。
并且保证所有能用 url 寻址找到的资源对象都支持同样的动词操作(比如增删改查),不支持的可以返回错误,但绝不能支持额外的方法。

至于别的,比如是完全用 /分割的 url 还是使用传统带的?和&的 url ,是使用标准的 http get/post ,还是把动词放在 body 里,似乎没什么区别。

请问这样理解对吗?
5456 次点击
所在节点    程序员
30 条回复
imzshh
2015-10-02 11:23:18 +08:00
@Lucius 阮大的文章当成科普文看看就行了,当成教科书来学习还是不合适的。在 RESTful 具体实践中多得是比“ URL 中能不能出现动词”这样的问题更加重要的问题要去解决,没必要在这个问题上多纠结。
看看 github 的 search api : https://developer.github.com/v3/search/#search-repositories
hantsy
2015-10-02 11:28:46 +08:00
@imzshh 大部分情况是可以利用 HTTP 语义避免,少数情况下不得回避这些原则(如 /auth/signup, /auth/signin, 查询参数太多时,可能改 POST 查询,通过 Body 传递更多的参数)。 Github API , Heroku 是设计上比较的 API 典范。

REST , Rechardson Mature Model 都是约定,不是规范。

但 HAL 是规范。
yangyuan
2015-10-02 11:33:26 +08:00
RESTful 本身 url 里只有可能有两种实体。
资源 和 服务,这样设计的目的是动词可以用 HTTP 的方法来代替。

私以为 RESTful 是一种 API 设计的规则样式,但这个规则样式并不是最直观方便的,也不是很适合浏览器。
很多被认为“错误”的用法,完全可以另总结为 “ ACTIONful ”,“ WEBful ” 什么的。
imzshh
2015-10-02 11:34:32 +08:00
@hantsy 是的,所以我一直说的是风格而不是规范。
PS :你例举的这个可以用 POST /access-tokens, DELETE /access-tokens/<token> 这样的 URL 形式。
codeek
2015-10-02 11:49:22 +08:00
RESTful 的简单理解,可以分成三个层次:
1. 所有的 URL 指代的对应物都是一组资源 - resources;

2. 基于 1 ,自然不适合在 URL 中使用任何动词,所以推荐直接使用 HTTP 标准中的动词(verb: GET, PUT, POST, DELETE)来表示对资源的操作;

3. Hypermedia as the Engine of Application State(HATEOAS). 简而言之,服务器的每次响应中应该包含当前请求资源所有相关联资源的定位信息。举个例子:请求分页,如果下一页请求已经枯竭,那么本次请求的响应中应该标识下一页请求的定位 URL 为空。
semicircle21
2015-10-02 17:36:45 +08:00
@Lucius
@imzshh
@canesten
url 可以用动词的名词形式, 比如 对这个主题的点赞操作, 我可能会设计成这样:
https://v2ex.com/t/225164/upvoters
点赞就发 post, 获取点赞者列表就 get, 删除就往这个 url 上发 delete.

是不是动词没什么好纠结的, 真正实践 restful 的时候, 远有比这个麻烦的多的坑... 特别是面向移动客户端的时候, 完全按 restful 设计往往导致一个界面要好几个请求才能加在完, 体验像 shi 一样.
msg7086
2015-10-02 20:14:42 +08:00
@Lucius 「上菜了,请动筷子吧」 = 禁止筷子以外的餐具
资源如果只能做 CRUD 动作的话,就等于要把一大票业务流程都归并到 Update 上,反而造成接口混乱。
比如我要有购买商品功能,要怎么设计路由?
karloku
2015-10-03 04:01:47 +08:00
其实参考了 elasticsearch 的 api 设计方式, 觉得 uri 里包含动词也不是一件天崩地裂的事情, 也就是在 crud 之外.
比如我有一串资源是 /items, 这些 items 是支持排序的, 那么我排序的接口应该怎么设计呢.

PUT /items
{
"_action": "reorder",
"params": {...}
}
这样似乎就会污染 update 这个街口, 变得很复杂

把路由放到
PUT /items/orders
操作实际上不存在的 orders 资源. 总觉得有种自欺欺人的感觉. 这种做法最常见的是用在搜索或者点赞上. 但是前者的确因为请求而产生了一次性的资源. 而后者也是可以勉强算是嵌套在某个资源内部的资源.

或者是针对所有资源进行
PUT /items/x
去更新每一个 item 的 order. 这个好像 restful 了, 不过使用起来会变的非常麻烦...

最后尝试下来做下来还是包含一个动词的 URI, 会让 api 的语义更清楚:

POST /items/_reorder
legendlee
2015-10-03 11:48:28 +08:00
@msg7086 没做过电商系统,但是按照之前做管理系统的经验,购买商品这种操作,在系统内部应该叫“创建一个订单”吧。
SmiteChow
2015-10-06 21:10:37 +08:00
最标准的 restful 可以参考 swagger 设计

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/225164

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX