不少程序员都是这么认为的,基于 HTTP API 的服务,只要用 GET 请求和 POST 请求就足够了。 像 RESTful 这样的 大量使用 PUT , DELETE 请求是不必要的。
真的吗,我来举一个例子。
假设有一类资源 ResourceXYZ ,对其有增删查改的操作。 如果只使用 GET POST 之类的设计方式,那么很可能会设计以下的请求接口:
POST .../addResourceXYZ
POST .../delResourceXYZ
GET .../getResourceXYZ?resourceId=resourceId
POST .../updateResourceXYZ
如果按照 RESTful 的 设计方式,很可能会设计以下的请求接口
POST .../ResourceXYZs
DELETE .../ResourceXYZ/{resourceId}
GET .../ResourceXYZ/{resourceId}
PUT .../ResourceXYZ/{resourceId}
现在假设,客户端要获取该资源,其 ID 为 resourceId 。 如果成功,那么一切都好说。 如果失败, Restful 的处理方式是,通过 HTTP status 返回错误码来表示原因,例如 404 表示该资源不存在。
那么只用 GET POST 两种方法的方式呢? 响应请求
GET .../getResourceXYZ?resourceId=resourceId
的时候能不能也用 404 呢?
按照 404 的语义,响应 404 是不对的: 因为客户端请求的 URL 实际上是正确的,只是对应的参数没有找到对应的结果 很多时候,就只能靠响应 200 然后返回空数据或者空对象来处理了。 例如 Content-type 为 application/json 时,可以返回 {} 或者
{
"error": "not found",
"code": 404
}
这样就会要求客户端,必须处理 HTTP 回复的具体内容,而不能只处理头部。 那么客户端要怎么处理这个 json 呢 要先解析 json ,然后尝试分别这是一个资源的内容,还是一个错误提示。
对于强类型语言例如 C/C++ OC Swift 写的客户端来说,恐怕就忍不住要问候服务端程序员一家了。
更重要的是……
没有库会支持这种拍脑袋式的设计。
全文完,欢迎拍砖。
1
6IbA2bj5ip3tK49j 2017-02-15 13:08:28 +08:00 1
问题在于,加上 delete 和 put 也是不够的。
那些状态码也是不够的。 |
2
wingoo 2017-02-15 13:08:55 +08:00
POST .../addResourceXYZ
POST .../delResourceXYZ GET .../getResourceXYZ?resourceId=resourceId POST .../updateResourceXYZ ============== 本身 api 端是按照模块划分的 所以 GET .../getResourceXYZ?resourceId=resourceId 可以划分为 GET .../getResource1 GET .../getResource2 restful 只不过帮你把这些定义自动划分好了而已 另外返回值, 默认为 200 正确,错误 会在返回代码里统一定义 |
3
Reign 2017-02-15 13:11:42 +08:00 2
其实,有 POST 就够了, GET 都是多余的
|
4
m939594960 2017-02-15 13:11:47 +08:00
主要是状态码完全不够用,大部分都需要 先获取一下 header 判断是否正确,然后解析 json 判断 code 代码。、
|
5
wingoo 2017-02-15 13:13:57 +08:00
至于前端调用解析结果, 这个不管是否使用 restful 都需要前端去判断
而统一的结构只会有好处, 不会有坏处 更何况, 错误还可以统一处理啊 如果这种设计叫拍脑袋设计, 那你所接触的系统基本都是拍脑袋了 奉劝下 lz 不要迷恋权威 restful 只是 restful 而已 |
6
cloudyplain 2017-02-15 13:15:03 +08:00 1
404 的例子理解不了,个人认为 restful 去掉了 url 中的动词",简化了 url 命名。
|
8
laxenade 2017-02-15 13:20:58 +08:00
反正都不遵守 restful 了 为什么还要遵守 404 的语义。
|
9
Matrixbirds 2017-02-15 13:29:38 +08:00
按照 spec 的 rule ,认为 get 的请求是不会对服务端状态造成改变的。 post 则会改变
|
10
noli OP |
12
undeflife 2017-02-15 13:35:19 +08:00
|
13
Sequencer 2017-02-15 13:35:20 +08:00 via iPhone
在 header 里面鉴权…
post 发 json 指令有啥不好的…… |
14
clino 2017-02-15 13:39:45 +08:00
我也只用 get/post ,其他都没用
|
15
noli OP @cloudyplain
URL 名称叫做 Universal Resource Location ,本来只是用来表明资源的位置。 而加上动作前缀,也不是不可以,但这种方式偏离了表示资源位置的本意,耦合了其他语义。 例如, getResource 返回 404 ,那么可以有两种方式理解: 1. 不看动词,表明该资源不存在 2. 看动词,表明 1 )不存在这种资源,或者 2 )不存在对这种资源的操作,或者 3 )资源存在但不支持这种操作 |
16
magict4 2017-02-15 13:46:31 +08:00 2
如果我有个 Email 的 Service , GET/PUT/DELETE/POST 分别对应增删查改,那『发送』,『存档』,『移到文件夹 X 』又该如何表示呢?
|
17
gamexg 2017-02-15 13:50:33 +08:00 via Android
没意义, 404 时想要返回错误信息还是需要解析返回的内容结构。
那直接 200 不一样吗? |
18
kenshinhu 2017-02-15 13:51:29 +08:00
我发现我一起用的是 假的 RESTful
|
20
noli OP @magict4
如果将 Email 视作 Resource ,或者更广泛地考虑,用 RESTful 来描述 IM 消息: 向某人发送消息,应该是在 其消息队列中 POST 一个新资源, 用 ``` POST /{SomeBody}/messages/ ``` 存档某消息,其实也就是同样的意思 移到文件夹 X 这里面略坑,因为包括两个步骤: 1. 在新位置复制一个 2. 在旧位置删除 看需要是否做成事务式的: 如果是事务式的,应该是事务队列增加一个资源 如果不是事务式的,那么分别执行 POST 和 DELETE |
22
magict4 2017-02-15 14:05:20 +08:00
@noli 我不会这么设计我的 API 的。 Messages 这个概念,是因为 Restful 只提供了 4 个动词的一种变通。我的 Server 可能通过 Message Queue 来实现消息的传递,但这种底层的东西不应该暴露给我的客户。我需要暴露给客户的,应该是类似 send email, archive email, move email 之类的接口东西,然而这并不能通过 Restulful 来直接实现。你可参考下 AWS 的服务文档
|
23
Felldeadbird 2017-02-15 14:08:59 +08:00
我个人认为 GPPD 最重要的优点在于 统一了 URL 操作,节省了起名的困难。
例如:现在 CURD 都是 /article/1.html 。 我都不用去想起他动作了。 换以前,/article/1.html , /addarticle/1.html, /updatearticle/1, /removearticle/1.. |
24
murmur 2017-02-15 14:11:43 +08:00
以现在的框架 restful 更多成为一种形式或者信仰 除了 json 发出和 json 结果比较讨人喜欢 其余的没啥问题
比如 /api/removeItem 和 /api/item 发 del 有什么区别么?前者如果命名一致文档合理同样是优秀设计 |
25
noli OP @magict4
我说的 Messages 是类似于论坛消息之类的业务 Message , Email 概念的泛化、抽象化。 你当然可以不用 Restful 来实现,而且我本人也不建议。 你要我举个例子,那我就免为其难了。 事实上,我认为,操作系统的全部 系统调用,都可以用 RESTful API 来对应表示。 不习惯的人可能会觉得别扭,但是是可行的、科学的、经得起考验的。 |
27
wshcdr 2017-02-15 14:14:07 +08:00
我认为采用 restful 的话, 客户端(包括移动端)是要自己维护自己的业务接口的,服务端只是暴露 GET/PUT/DELETE/POST 分别对应增删查改
对应发邮件的例子,也就是客户端要自己实现发送这种功能,自己在发送功能里协调对 GET/PUT/DELETE/POST 的调用。 |
28
mcfog 2017-02-15 14:17:46 +08:00 3
1. restful 是风格不是规范
2. 如果楼主如果真心认为“ POST /updateXYZ?id={id}”和“ PUT /XYZ/{id}”对等,那我觉得并不能说是真正理解了 restful 3. 正如其他很多同学说的, restful 的状态码数量有限,用于表示复杂的业务问题经常不够,基本最终还是要在 body 里定义自己的错误描述体系 4. restful ,状态, cookie , session 之间的关系我一直没找到权威说明。业界常见的 restful 风格接口大多用非 cookie 的令牌 token+服务端 session 来处理状态,此时接口连基本的在 web 端和 app 复用都得讨论了( token 让 js 自己存储和 secure httpOnly 的 cookie 的安全性差距)欢迎指教 5. 把接口分两大块: a) 业务接口( app/web 等使用的),这类接口我倾向全 POST 或幂等读 GET 其他 POST ,返回结构统一 code,message,body 的风格, HTTP 状态码用来表述“通信状态”, body 内返回吗表述“业务状态” b) 后端接口( CGI 端再调其他 server 用的),这类接口如果业务逻辑量小,贴近“资源 CRUD ”的 restful 最贴切的领域的话,我会考虑 restful 作为备选方案 |
29
magict4 2017-02-15 14:22:17 +08:00
@noli 你看看我有没有误解你的意思。拿『移动到文件夹 X 』举例。
如果是事务的,我猜你对应的 URL 会是 post .../MoveEmailTransaction 如果不是事务的,你说会用两个 HTTP request 来实现,那对应的 URL 肯定跟上面的会有所不同。 如果我的理解是对的话,同样的一件事情,因为实现不同,对应的接口变了。在我看来,好的 API 设计应该是无论实现怎样, API 应该保持稳定。所以我会用 post .../moveEmail?source=???&&destination=??? > 但是是可行的、科学的、经得起考验的 如果因为实现的不同,需要改变 API 的设计,我不太能认同是科学的。 我的主要观点是, Restuful 提供的 4 个动词是远远不够的。在复杂的业务场景里面,如果想用这 4 个动词来表示所有操作,往往会让 API 的设计变的更加困难。 |
30
baiyi 2017-02-15 14:22:35 +08:00 1
RESTful 说到底也只是众多 Api 规范 中的其中之一, 它是有一定的适用性的.
在 RESTful 适用性之外的项目,就不要强行上 RESTful 了 现在 Api 的规范都和语言之争一样火爆了...... |
32
otakustay 2017-02-15 14:34:31 +08:00
restful 是架构风格,不是接口设计风格,如果你做不到 restful 架构,请不要在接口这么个东西上盲目追求 restful
|
33
gevin 2017-02-15 14:37:52 +08:00 1
又想提一下我原来写的两篇博客:
RESTful 架构风格概述: http://blog.igevin.info/posts/restful-architecture-in-general/ RESTful API 编写指南: http://blog.igevin.info/posts/restful-api-get-started-to-write/ |
34
noli OP @magict4
在一个 openstack 相关的业务里面,我用 RESTful 实现过对 AD ( ActiveDirectory )相关的接口 WEB 封装。 里面也是经常有对各种简单的、原子的 对各种 AD 条目的操作的 组合所形成的事务。 提交事务方法只有一种: ``` POST .../Transaction ``` 然后在请求体里面用 JSON 描述这个事务的各种操作和参数,例如: ``` { [ {"method": "POST", "resource": "/someResources", "args": {...} }, {"method": "DELETE", "resource": "/someResource/1234"}, ] } ``` 实际上就是把一连串的 RESTful API 调用转化成一个 JSON 对象来描述要执行的事务。 所以你说“同样的一件事情,因为实现不同,对应的接口变了” 实际上不存在~ :) |
35
zweite 2017-02-15 14:47:31 +08:00
想象当 Restful 遇到爬虫会怎么样
|
36
msg7086 2017-02-15 14:50:06 +08:00
为了去套 RESTful 而强行把不是资源或者不适合以资源形式访问的东西也当做资源,就是个问题了。
这有点像数据库的范式,你可以把范式堆得老高,但是实际开发中没人会真的这么干,意思意思做得干净点就行了。 顺便提一句,很多实现里(比如浏览器), HTTP 动词是只支持 GET/POST 的, PUT/DELETE 都要用 _method=? 之类的来传递,然后在上层去抽象。 |
38
whx20202 2017-02-15 14:51:58 +08:00
|
39
baiyi 2017-02-15 14:52:04 +08:00 1
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
这篇文章是我看来关于 Api 中 RESTful 的实践 中最好的一篇文章了 想要更深的了解 REST,可以去找找博士的论文读 |
40
wizardoz 2017-02-15 14:55:43 +08:00 2
非要说够不够的,那我说一个 POST 就够了,还要 GET 干啥?
所以我们要的不是够,我们要的是优雅。 |
41
fucker 2017-02-15 14:59:55 +08:00
POST .../ResourceXYZ?action=delete/add/update
|
42
kulove 2017-02-15 15:01:58 +08:00 via iPhone
风格而已,没必要完全遵守
|
43
noli OP @wizardoz 说得太好了。要的就是优雅。
那些说 RESTful 是 风格而不是规范的同志们,扯这个没用。 你看看各大平台下的各种 RESTful 相关的库,你就知道什么是风格什么是规范了。 遵守这个风格也好,规范也好,就提供一种使用开源代码的机会。 不遵守也不是不行,自己掌握细节,然后实际上是把 RESTful 的规范用另外一种形式实践一遍。 |
44
neutrino 2017-02-15 15:08:55 +08:00
即使是资源的 CRUD ,也不推荐用 Restful 。 HTTP 状态应当仅由 HTTP 服务器处理,如 404 是指没有找到处理的程序,而不是程序处理了发现资源没找到。任何经处理的结果应当一律以 HTTP 200 返回,表示这是一次成功的 HTTP 请求,并在 body 中表示请求的结果。
|
45
noli OP |
46
neutrino 2017-02-15 15:34:58 +08:00
@noli 对于动态处理的内容不应当缓存,不推荐 urlrewrite ,每一个 url 都应当是实际存在的文件,仅缓存静态文件。应当显式暴露入口文件。
|
48
hxtheone 2017-02-15 15:45:25 +08:00
请求方式表示行为, URL 表示资源, 个人表示很喜欢, 在 URL 里带上动词总是感觉太啰嗦了点
|
49
noli OP @neutrino
“动态处理的内容不应当缓存”? 明明基于 HTTP 动作、状态码和特定 HTTP 头就能实现的事情,硬生生因为你非要返回 200 而自废武功。 “每一个 url 都应当是实际存在的文件” —— HTTP 3XX 也可以不用了是吧? 所以你这是把规范的实现的效果,在写代码的时候实践了一遍 还不如老老实实遵守全套的 RESTful 规范呢 |
51
PhilC 2017-02-15 15:55:56 +08:00
```
POST .../Transaction ``` 然后在请求体里面用 JSON 描述这个事务的各种操作和参数,例如: ``` { [ {"method": "POST", "resource": "/someResources", "args": {...} }, {"method": "DELETE", "resource": "/someResource/1234"}, ] } ``` 你这个是 restful ? |
52
hronro 2017-02-15 15:55:56 +08:00
所以讲道理,最终还是 GraphQL 最好😂
|
53
menc 2017-02-15 16:00:05 +08:00
逻辑不对啊, 404 , 403 状态码是针对 URL 的,不是针对动作的,它只能标识该 URL 的相关信息,不能用状态吗来作为后端逻辑执行结果的证明。
|
54
lxrmido 2017-02-15 16:00:24 +08:00
你说得很有道理,假如我是三十年前的程序员我一定支持你。
|
55
noli OP @PhilC 里面的 JSON 是手打的,确实是格式不对。
但 POST 一个 JSON 有什么问题么? 为什么觉得不是 RESTful ? |
56
noli OP @menc
https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6 The Status-Code element is a 3-digit integer result code of the attempt to understand and satisfy the request 所以并不是只针对 URL 的。 事实上 HTTP 405 Method Not Allowed 就是针对你的说法的反例。 |
57
PhilC 2017-02-15 16:10:12 +08:00
```
{ [ {"method": "TEST", "resource": "/someResource/1234"}, ] } ``` 我 POST 一条这样的 JSON ,你是不是也要返回 HTTP 405 Method Not Allowed |
58
rogerchen 2017-02-15 16:15:48 +08:00
以前是绝对路径 / 后边是 CGI ,?后边是传给 CGI 的参数。
restful 把参数写在路径里,搞万物都是 URI ,方法作为动作参数。 我个人觉得就是两种不一样的范式, restful 主要搞 CRUD 这种比较简单的东西, CGI 更适合搞参数比较复杂的系统。 |
61
noli OP @PhilC
在我那个实现里面, POST Transaction 的时候大多数情况下返回 200 以及事务 ID 然后根据 事务 ID 查询 事务状态的时候,会给出事务的状态、结果什么的。 当然,这个设计是有不足之处的,例如 事务里面的前后两条如果有输出间的依赖关系的话,目前是实现不了的。 但是,你举的这个例子也太 TM 弱智了吧……? |
62
hronro 2017-02-15 16:38:59 +08:00 1
|
64
Sight4 2017-02-15 17:02:26 +08:00 1
这个 topic 在 V2EX 已经引战 N 次...
1. 在经历多个前后端分离的坑之后,从结果上看,完全符合的 restful 规范风格的 api 是很难实现(应该说是实现起来反而很别扭) 2. 但是 restful 风格的 URL 、幂等性、授权对于设计基于 web 的 api 是很有指导意义的,所以最终在项目实施的时候,很多时候都会按照资源来划分 url ,但是不再使用 http 返回码以及 method 来表达资源的结果和用途,毕竟, API 文档还是要写的嘛 3. 其实,统一的 http post 在某种意义上很方便前端对 api 的封装 |
65
chairuosen 2017-02-15 17:06:30 +08:00
又来引战了
|
66
noli OP |
67
baiyi 2017-02-15 17:37:36 +08:00
@Sight4
@chairuosen 虽说我也认为楼主有点引战的意思. 但是,这类的"战争"我觉得还是有一定意义的. 能引得起来,就说明还是存在着许多人不认同的地方,有了更多的讨论,融会贯通嘛,对自身的理解也很有帮助 |
68
noli OP @Sight4
1. 因为很多人根本没有操刀设计 API 的水平。别说 RESTful 了,我厂也算知名互联网企业,某 C++ SDK 出品一样是个渣渣。 RESTful 要考虑的更多难度更高,但说 RESTful 会导致实现别扭…… 呵呵 2. HTTP 返回码和 回复里面的返回码,通常其含义不应该是冲突的,诸如 HTTP 200 但是 "code": 404 这种只能说某些人自以为很了解 HTTP 协议及其客户端。 3. 不用 HTTP method ,那么基本上就是把动作写在 URL 里面,这种设计我觉得见仁见智,有些时候是很省事,但通常深挖一下就会发现是解耦不够。 更重要的是,这基本上等于放弃了各种 RESTful client SDK 带来的好处。 那还不如直接点干脆不用 HTTP 所以我觉得你说了很多没有经过深入思考的经验,但基本上是废话。 |
69
guokeke 2017-02-15 17:41:36 +08:00 via Android
restful 已死。 graphql 当立。
|
70
Sight4 2017-02-15 18:10:58 +08:00 via iPhone 1
@baiyi 唉,主要是每次引战,非得要说那个是适合,那个不适合,抛开场景来啥扯一般很难有结论, restful 优雅,但 db 设计的三范式何尝不是?度是很重要
|
71
cnt2ex 2017-02-15 18:20:12 +08:00
URL 不是 Uniform Resource Locator 吗?
|
72
Actrace 2017-02-15 18:30:25 +08:00
猩球大战开始了。
|
73
Lucups 2017-02-15 18:42:56 +08:00
同样的话题这已经是我看到过的第 4 篇 topic 了。
看到现在的评论,我的感觉是大多数人倾向于: restful 不错,有借鉴意义,但我只会有限使用或者在不会去用。 |
74
lightening 2017-02-15 18:52:29 +08:00
@magict4 仔细想的话,其实都是对资源的操作。
发送是 CREATE 了一个 delivery ,移动和归档是 UPDATE 了状态(或位置,取决于你的实现)。我倒不是觉得做 API 应该永远按照 RESTful 设计,但确实仔细想想的话,确实至今我没有遇到任何不能 fit 进 REST 的操作。 推荐 DHH 的关于 RESTful 的演讲: |
75
jsq2627 2017-02-15 20:13:22 +08:00
restful 是信仰,不是一言两语能说清楚的。
https://github.com/Microsoft/api-guidelines/blob/master/Guidelines.md |
76
pathbox 2017-02-15 21:31:41 +08:00
怎么会没有人用呢
|
77
zhengkai 2017-02-15 21:36:35 +08:00
忘了 RESTful 吧,去了解 GraphQL
|
78
zonyitoo 2017-02-15 23:25:55 +08:00
其实 GET 也是多余的,只需要 POST
|
79
Balthild 2017-02-16 01:06:52 +08:00
@noli 别转移话题,我说的不是什么东西比 REST 更优雅,我说的是在不用 REST 更优雅的前提下就不要用 REST 。
请求的东西不是资源时, REST 一点都不优雅。 |
80
noli OP @Balthild
你要说优雅,那你优雅的标准是什么?举个例子都没有,我很难跟你说话哦。 又说请求的东西不是资源,什么东西不能视作资源来被管理呢?除了无限的东西之外。 你没有办法用合适的方式把要管理的东西视作资源 ——我见到的很多程序员都这样,例如楼上某层不知道事务怎么用资源视觉来处理—— 就说 RESTful 不优雅,这是拒绝承认自己有问题。 |
81
magict4 2017-02-16 05:22:20 +08:00
@lightening 我暂时还没开看你贴的视频,有时间的话会看。
如果我没有理解错,你跟楼主的意思应该都是 sendEmail 对应的是 createDelivery moveEmail 对应的是 createTransaction 之所以会有这样的对应,是因为 Restuful 只提供了 4 个动词。有了这样的限制,我们不得不对资源名字进行变换,把 email 变成 delivery 和 transaction 。 我同意你说的,我们总是可以想办法把 API fit 进 Rest 这个框架 /风格。但是我不能认同我们应该这样做。 |
82
TigerS 2017-02-16 06:55:05 +08:00
小网站感觉完全够用,但是如果稍微大点就不太方便。
例如 DigitalOcean API ,我们自己写一个小的管理的时候基本上是 ``` api_url: 'https://api.digitalocean.com/v2/' def action(action, droplet_id): blah_blah(api_url + 'droplet_id' + action) ``` 只是举例,随便写了点 很多东西都可以调用,而且简单易懂,而且很多可以重复利用 但是如果全是 post 的话,就需要不断确认是 post 到了哪里,虽说也可以,但是有时候并不好用。 |
83
baconrad 2017-02-16 10:46:57 +08:00
以前端來看,今天我使用
`GET .../ResourceXYZ/{resourceId}` 結果 server 回傳 HTTP status 404 請問以下哪個原因才是正確的? 1. client 端網路環境出問題。 2. server 端網路環境出問題。 3. url 輸入錯誤。 4. 我要求的資源不存在。 |
84
ShiningRay 2017-02-16 10:47:26 +08:00
你说的是以 RPC 的风格来设计 API
另外楼主肯定用了很麻烦的对 restful 不友好的框架 |
85
mqtt 2017-02-16 11:46:07 +08:00
POST .../addResourceXYZ
POST .../delResourceXYZ GET .../getResourceXYZ?resourceId=resourceId POST .../updateResourceXYZ 这样的命名我是无法接受的,又长又丑。 资源不存在, 本来就应该提示 404 啊, 表明用户访问的资源未找到,这样客户端就可以通过 response code 知道自己请求的资源不存在。 |
86
mqtt 2017-02-16 11:46:46 +08:00
response status
|
87
changwei 2017-02-16 11:50:25 +08:00 via Android
这种争论可以直接参考大公司的最佳实践。
你们去看一下大公司的 app 接口就知道了,像百度腾讯的 app 接口都只有 get 和 post ,然后返回的 json 里面有专门的错误码,错误消息解释和消息体。 |
89
baiyi 2017-02-16 12:34:12 +08:00
@changwei github 不光有 RESTful 的, 还有 GraphQL 的
国内的公司没有, 只能说明他们不去接触新东西,或业务不合适,代表不了其他的什么 |
90
jybox 2017-02-16 12:43:17 +08:00
其实我的想法和楼主差不多(两年多以前我也在 V2EX 发过类似的帖子),即我是觉得 RESTful 并不能覆盖到所有的情况,硬要把不适合的业务对应到「资源」是个费力不讨好的事情。但确实如果能够顺着 RESTful 的思路的话,会有一些比较方便的工具可用,所以也没有必要非要「不遵守」 RESTful 。所以我觉得在做 API 设计的时候,最重要的是项目本身能够统一和自恰,适合 RESTful 的部分就用,不适合的情况也没必要硬往上靠。
RESTful 和 HTTP 本身的关系并没有那么密切,关于如何设计基于 HTTP 的 API 实际上不止 RESTful 一个方案。 |
91
loading 2017-02-16 12:44:07 +08:00 via Android
只是参考,用 get,put,post,dekete 对于我来说就是可以少写几个路由。
|
92
noli OP |
93
noli OP |
94
wizardforcel 2017-02-16 14:08:16 +08:00
动态路由不等于 REST ,非 REST 也可以用动态路由 GET /ResourceXYZ/{resourceId}。
别什么都往 REST 上套。 |
96
wizardforcel 2017-02-16 14:16:07 +08:00
以及。。很多 http 客户端库不支持除了 get 和 post 之外的方法,遇到这种情况我真是。。。
另外不用 REST 照样也可以设计出来优雅的路由 增: POST /ResourceXYZ/create 删: GET /ResourceXYZ/{resourceId}/delete 改: POST /ResourceXYZ/update 查: GET /ResourceXYZ/{resourceId} |
97
noli OP @magict4
我觉得设计 restful api 的时候很重要的一点是,要弄清楚业务理念哪些概念是原子性的,哪些操作是可以通过多个对原子性概念的操作组合出来的。 如果你觉得让客户端来做这些原子性动作组合,是要求太高,那么你可以加一层 api 来接收客户端的意图,然后在这层 api 之下实现业务, 这样通常能解决很多所谓 fit 进 restful 的问题 |
98
wizardforcel 2017-02-16 14:30:09 +08:00
@noli
> 又说请求的东西不是资源,什么东西不能视作资源来被管理呢?除了无限的东西之外。 如果不用 REST ,某些 API 我就可以设计成 /login /reg /tranfer 用了 REST 就没有这些简明扼要的设计,这是不是增加复杂度呢?? |
99
wizardforcel 2017-02-16 14:33:27 +08:00
@noli
> 如果你觉得让客户端来做这些原子性动作组合,是要求太高,那么你可以加一层 api 来接收客户端的意图,然后在这层 api 之下实现业务, 客户端做原子性动作组合存在安全隐患。 服务端里增加一层 API 嘛。。为什么我要在 HTTP API 里面调用 HTTP API ,而不是直接调用 DAO 或者 ORM 呢??没你这么抽象的。 HTTP API 就不是给服务端自己调用的,这样粒度比 DAO 大多了。 |
100
noli OP @wizardforcel
/login /reg /transfer 你能用这种方式设计这些 api ,恰好说明了你的业务不需要把这些行为视作资源。 如果你需要满足这些需求的时候,你就自然要用 restful 了 1. 查询某用户在某时段内的 login 记录 2. 针对某些注册申请进行人工审核,或者拒绝或者 forward 3. transfer 是异步的,需要实时关注 transfer 是否完成 你没有这些需求,你当然不需要把这些视作资源。 关于“为什么要在 HTTP API 里面调用 HTTP API ” 没有为什么,我不关心实现,因为这只是为了适应低能的客户端,怎么实现是业务需要问题。 至于为什么 HTTP API 调用 HTTP API ,那是因为 do not repeat your self. 当这些被调用的 更底层 API 实现有变动的时候,你不需要改高层 API 的实现,虽然这也不一定是必须的。 你连这个道理都不懂,我感觉我们的层次有差距啊。 |