RESTful 有用吗? HTTP 有 GET POST 就足够了?

2017-02-15 12:59:26 +08:00
 noli

不少程序员都是这么认为的,基于 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 写的客户端来说,恐怕就忍不住要问候服务端程序员一家了。

更重要的是……

没有库会支持这种拍脑袋式的设计。

全文完,欢迎拍砖。

42350 次点击
所在节点    程序员
207 条回复
bravecarrot
2017-02-18 00:25:34 +08:00
其实从模块儿设计的思想来说
restful 是符合 高内聚,低耦合 的

就拿 lz 的例子来说, url 分发的模块和逻辑处理的模块应该尽可能的分开,你设计了 add del modify and so on ,但是业务逻辑更多的时候呢,需要修改的时候怎么办?从 url 到逻辑代码都要修改。

采用 restful 的方法,都到一个地址
后端的人想怎么写就怎么写,不同的人写不同的模块,都处理 json 就行了。功能增加,功能修改都只需要改后台逻辑部分就行了

最开始做东西 就按 lz 的思路做的,每一个操作都一个 url ,工作量非常大!后来了解到 restful ,简直是艺术
bravecarrot
2017-02-18 00:28:08 +08:00
搞错 lz 观点 尴尬😅
LINAICAI
2017-02-18 00:50:05 +08:00
然而大部分后台开发人员都不按照这个来,几乎都只有 post 和 get 。
thekll
2017-02-18 02:02:36 +08:00
RESTful 是一种针对互联网应用系统的架构风格( architectural style ),有非常明确的应用场景及要求。
REST 化对系统性能、灵活性、统一接口、移植性、可靠性等方面都有好处。

如果不以系统架构(客户端、服务端)的角度考虑问题,只考虑服务端内部如何方便实现,不考虑客户端,是没办法理解为什么要 RESTful 的。

反对的,也应该拿出点干货。
有些根本就不知道 RESTful 的目的。
lygmqkl
2017-02-18 11:42:07 +08:00
第一 如果一定要使用一个一定是 post ,而不是 get ,所以精简一些 post 就足够了。

第二如果你觉得 get and post 对你同意重要,那么你肯定需要 put delete and option 。包括 resource 和幂等在内的一些概念真的很棒!

最后国内有太多伪 RESTFUL ,合作过一些大项目出来的 a or i 工程师简单粗暴的觉得 post 可以代替 put 也是醉了
smallpath
2017-02-18 12:44:10 +08:00
百万级别的 api 调用次数很多?/手动 AC 扇子脸
lslqtz
2017-02-18 13:35:26 +08:00
post 同样可以理解为向服务器传递消息,通过参数来说明动作
实际上,普通的带参数 get/post 单个请求能完成的 不应用 restful 多次请求增加负担
优雅是一方面 负载同样重要
noli
2017-02-18 16:05:00 +08:00
@lslqtz

不明白为什么 RESTful 对你来说居然是代表着多次请求才能完成普通 HTTP 请求。
或许你就是哪种又不懂又要(有意或无意地)泼脏水的
果然无知就是罪恶啊。
lslqtz
2017-02-18 18:34:33 +08:00
@noli 指的 move copy 等请求
noli
2017-02-18 19:36:56 +08:00
@lslqtz

我只是举了在我那个系统里面的做法为例子,并且是针对带有事务性质的要求,用基本动作的组合来描述一个事务。
没有人说过 RESTful 语义做那种看起来是多个请求组合的方式就真的一定要发多个请求。
既然你可以说的出“ move copy 等请求”
想必用 RESTful 语义 POST a move POST a copy 也不是什么难题吧?
Balthild
2017-02-19 01:35:42 +08:00
@noli 抱歉啊,你又找错人了。
你应该找一开始说「只是要优雅」的人去要优雅的定义,毕竟这句空话是他先说的。而且,我看你好像还回复了他来表达赞同,所以我相信你知道我说的是谁。

邮件的例子,你举是举了,然而却搞出一堆什么事务啊队列啊之类的东西,越搞越复杂。如果不用 REST ,就是传一个自定义动词 move 的事情,显然比 REST 更优雅。
Balthild
2017-02-19 01:43:07 +08:00
手里拿着锤子,看什么都是钉子。
殊不知排钉得用气钉枪打,用锤子只会把它锤弯。
noli
2017-02-19 02:17:31 +08:00
@Balthild

那是因为我给了一把索尔的锤子。当然可以把所有东西当钉子了咯。
事务和队列确实是业务需求,跟 RESTful 无关。
因为你不知道实际上我做的事情是用 json 做了一个 DSL 来描述事务。
这的确跟 RESTful 没有直接的关系。
但如果不是 RESTful 的方式解构所有资源操作,你根本就不可能像我那样用 JSON 来描述所有的事务动作。
你必须一个一个事务地去实现而不是像我写的那个系统那样,把要做的事务交给调用者来定义。
跟你们这些靠勤奋的锤子比,我都不好意思了。
Balthild
2017-02-24 10:56:28 +08:00
@noli 你看,你这样不就是不优雅吗——对于前端而言,事务的概念本应是不可见的,而你却为了遵守 REST 强行把锅甩了。
noli
2017-02-24 11:19:22 +08:00
@Balthild 我来指出你思考问题过程中的一些缺陷请你不要介意:

1. 为什么“对于前端而言,事务的概念本应是不可见的”? 这是一定的吗? 这是业务决定的,还是只是你的信念?如果事务是客观存在的,前端可以有什么办法视而不见吗?

2. 即使 ““对于前端而言,事务的概念本应是不可见的” 是成立的, RESTful API 就做不到让前端不觉察事务的存在吗?

3. “甩锅”这种事情,请问跟是否 RESTful 的关系是什么?难道你认为,假如有人想把锅甩给服务端,服务端可以用 要遵守 RESTful 来拒绝吗?

你看,你的论点基于很多你个人的经验和没经过深入思考的假设。

没错,如果遇到你这样的同事,我就可以墙裂推荐 RESTful 来甩锅,毕竟写 RESTful 规范的人比你牛逼。
有本事你也写个规范出来让大家讨论讨论,光坐在一旁拆台不体具体建议,这种事情也不是特别难做吧。
Balthild
2017-02-24 14:23:17 +08:00
@noli

1. 首先现在为什么前后端分离是趋势?那就是因为前端本应只考虑对资源之操作的动作,而不应考虑操作的实现细节。事务的概念已经属于实现细节了,因此不是前端该考虑的。

2. RESTful 的 API 只有四个动词,所以对于动作的描述能力极其有限。

3. 为了在不方便遵守 RESTful 的地方遵守 RESTful(请注意这个前提)而拒绝实现某种方法,称为甩锅的确不准确,应该直接称之为设计缺陷(这个词针对 API 而不是针对 RESTful)。
在上面的例子中,对邮件的操作你可以放一个事务,里面的细节是删除再新增,那么如果是对一个几 GB 的对象的操作呢?
Balthild
2017-02-24 14:28:23 +08:00
@noli 至于我设计的 API 风格肯定没有 REST 的牛之类的话语,这属于转移话题。原本在讨论 REST 风格好不好,你却转移到我设计得好不好。
noli
2017-02-24 14:43:52 +08:00
@Balthild

1. 请问新浪微博 API Twitter API Facebook API 这些,前后端分离在哪里?他们是不是 RESTful ?
再强调一遍。前端不行是前端的事;前后端分离是前后端分离的事;前后端分离之后如果有事务,即使不用 RESTful 前端一样要有事务的概念。 RESTful 能解决这些问题,但并不是只解决这些问题,你拿这些来说 RESTful 不行是因为 你不行。

2. 可是使用 RESTful 的人可以有无数种抽象出资源的方式。显然你不行,所以你用不了 RESTful 。

3. 删除 GB 级别的操作又怎么样。你写代码的时候,知道有异步操作,知道可以用 Promise 或者 Task ,怎么在设计 RESTful API 的时候就不懂设计 Promise 或者 Task 资源? 这是你蠢还是 RESTful 蠢?
noli
2017-02-24 15:03:20 +08:00
@Balthild

说你只懂拆台不懂具体建议,是因为 RESTful 有现成的例子所以你可以发出数不尽的批评而不需要意识到自己的不足。

我之前已经说过了,只要你想清楚了,你可以再做一份自认为比 RESTful 更好的规范。如果没有, RESTful 本身是一套很好的规范。从上下文来看,你批评 RESTful 的地方恰恰都是你没有想清楚的地方。

没错,我是想转移话题——你还没够资格批评 RESTful 哪里不好,或者没有到点上。
Balthild
2017-02-25 16:36:39 +08:00
@noli

1. 如果不用 RESTful ,前端可只考慮不可分割的「動作」之概念。每個「動作」對於前端而言都是原子性的。

2. 既然事務也可以抽象成資源,那何不把整個 API 改成這樣:原始的資源能 GET ,其他對資源的操作皆 POST 至 /transaction 。這樣不還是只需要 GET 、 POST ,不需要 PUT 、 DELETE 。反正事務也是一種抽象的資源,這很 RESTful 啊~

3.
> 删除 GB 级别的操作又怎么样
我說的不是刪除,是移動。難道你移動一個幾 GB 的對象時,是先刪除它然後再於其他位置創建?難道為了套 REST ,是可以連效率都捨棄的?

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

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

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

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

© 2021 V2EX