同事说:后台接口不能使用除 post/get 之外的方法,path 里不能带参数

2020-01-02 16:42:17 +08:00
 unco020511

我写了接口文档,尽量按照 RESTful 风格写的,然后前端+部分后台同事说不能用 put 和 delete,还有 path 里不能带参数; 我问为啥,他说这样不规范 我该如何说服同事?

获取对应学期下评语:[get] /back/remark/{termId} 删除数据:[delete] /back/record/{recordId}

22186 次点击
所在节点    Java
181 条回复
index90
2020-01-03 15:21:41 +08:00
哎,又是月经贴。
RESTful 本身不能算规范,更像是方法论,它告诉我们一种“说得通”的如何设计 API 的方法。并不表示它就是规范,全互联网只能按照它这一套来设计 API。
RESTful 的目的,是让 http method,url 具有了语义,简言而之,就是你看了我写的 method 和 url 上的单词,你就知道我的 API 是用来干嘛的了,不需要我额外的文档描述。这是它的最最最主要目的。
而网络传输,路由策略,网络安全等等,均不在 RESTful 所讨论的范畴里。

在你吐槽别人没有遵循 RESTful 那一套时,能不能先了解一下别人如此设计 API 的目的是什么?基于立场去讨论问题,是没有意义的,你连对方的立场都不许了解,上来就喷。

再来说规范,规范是一起共事的人达成的一种共识,价值在于降低沟通成本。如果你的团队已经有一套已经达成共识,大家已经熟知的约定时,你不应该去打破它,而是尽快掌握这套约定,成为团队的一员。如果你继续坚持你所认为的规范,让团队所有人都迁就你,那就已经失去规范本来的意义。
unco020511
2020-01-03 15:35:30 +08:00
@index90 是不是月经贴我不知道,因为我确实是第一次在 v 站发开发相关的帖子;我也没喷啊,哪个字眼开出来我喷了,反倒是你....
lihongjie0209
2020-01-03 15:48:29 +08:00
@unco020511 #136 很多情况下安全都是客户找第三方去做的, 你不可能去要求安全团队做什么
fkdog
2020-01-03 15:49:34 +08:00
@bnm965321
阿里云 OSS 这套 restful API 是完完全全照搬亚马逊而不是阿里云自己设计的。
亚马逊 S3 现在云存储服务的事实标准。各大云服务产商的云存储服务都实现 S3 api 的兼容。
fkdog
2020-01-03 15:58:35 +08:00
@binux 所以,不用 restful 就是走泥巴路哦?用 restful 就是拓宽道路走向更远的未来?
我可以研究的东西有好多好多,为什么要花时间在一种设计风格上争论个没完没了?
存粹一个设计风格取舍的问题也能扯到 35 岁。你独清?

真以为现在互联网项目是像以前传统软件开发一样一套代码可以流传个几十年呢?就现在中国互联网开发速度,一套代码能撑五年以上就已经很不错了。基本上转了 4、5 手面目全非,然后等着下一轮重构了。

而且现在架构风格都在往微服务架构方向转,在微服务架构方向下,那些代码解耦合、可扩展、维护性之类的工程方面优势也就没有那么重要。
index90
2020-01-03 16:03:21 +08:00
@unco020511 人贵有自知之明,自己看看自己发的贴,同事已经告诉你不能用 put 和 delete,并告诉你原因,这是他们的规范。而你的问题呢?
你不是问,这样做主要出于什么考虑呢?而是问,我应该如何说服我的同事?
背后潜台词不就是:我的同事竟然称之为规范,哈哈哈哈,笑死人了,这年头竟然还有不知道 RESTful 才是规范的人,v2er 各位评评理,我该如何怼回去。(当然这里我用了夸张修饰啦)
markgor
2020-01-03 16:24:03 +08:00
@binux 哈哈,又見面了,上次我記得也是在說 api 規範上面討論過。
首先我認同你所說的,我年輕時候也是這樣想,為什麼沒有人能打破陳舊?
但每次打破陳舊的背後背負的責任實在太重了,現在年近 30,雖然沒達到你說的 35,但我的思想已經接近了,以前留下來,沒有大問題,不做修改。

回到題主的問題中。
我不可能頂著壓力,跑去懟全世界,要求把 api 接口都按 resetFull 重新設計,然後說出一大堆冠冕堂皇的理由,但最終明眼人都能看出來,這小子為了“好看”,“跟風”所以要求改。
老實說,使用 PUT/PATH/DEL 來處理對應的業務,除了優雅外優點在哪裡?


對了,不是不願意學些,而是不願意在生產環境上學習。
我記得你說過你的業務基本是對接海外的產品,那麼我只能說國內環境不一樣。
就權當我能把運維前後端說服了,
大家都願意去對現有系統進行修改。
然後後端出現了一個新的問題。
此時此刻,後端心理肯定在罵我的,甚至還想甩鍋給我。
國內的環境你有時間可以看看阿里雲的前世。
binux
2020-01-03 16:41:45 +08:00
@fkdog #145 是,因为你不知道什么是好的。不管你做什么,做再多也没用。
@markgor #147 我比你大一些,这里面首先是个态度问题。知道什么是好的设计,什么是 bug,什么是 feature。
而且就 LZ 这个问题,你知道 X-HTTP-Method-Override 这样的方案吗? API 设计还是 restful,但是可以 fallback 全都是 POST。这样是不是既满足了优雅,又符合业务了?
从小的地方,这里改一点,哪里推进一下。当真的要推一个重新设计的时候,你会发现这时就不这么难了。
iCD
2020-01-03 17:04:25 +08:00
支持 get 不错了 我们只能写 post 接口
tianshiba
2020-01-03 17:04:46 +08:00
@binux 哈哈,你的观点真好笑。
enjoyCoding
2020-01-03 17:12:03 +08:00
从 http 语义的理解上不应该使用 delete,因为现在大多数不回去删除数据,而是将更新数据库的标志位.
至于 put 用于更新是没有问题的.
hantsy
2020-01-03 17:15:30 +08:00
@sunzongzheng 你公司是手动从 Socket 分析的吗?

如果用 Spring,或者 Jaxrs 都很容易,即使是用一些纯 HTTP 客户端,如 OkHTTP,Apache HttpClient,也很简单吧。
hantsy
2020-01-03 17:19:54 +08:00
@index90 公司内部 API 设计怎么烂都不要紧, 自己人调用随便怎么搞,外人都不好说你的好或者坏,只要你老板认可就行了。

但是,如果是对外公开 API,不遵循标准或者约定( REST 也算是一种约定吧),总说不过去,你总不能强迫别人去用你的一套吧。
hantsy
2020-01-03 17:22:40 +08:00
@binux 这种 Fallback 设计还是可以接受的,Spring 本身也是支持 Method Override 的。
markgor
2020-01-03 17:47:18 +08:00
@binux

你知道 X-HTTP-Method-Override 这样的方案吗?<---確實之前不知道。
但剛看了,需要後端配合,當收到 X-HTTP-Method-Override 時候重寫 method。
但其實就是過了安防那一塊吧,waf 等不需要進行處理,nginx 等也不需要額外配置其他。
還有就是後端一開始如果是完完全全按 resetfull 設置的話也可以不用進行修改。

但是如果我援用 POST 來跑,除了優雅,性能上有多大的區別呢?

如果是新開發的應用,用什麼大家提前說好了我覺得問題不大。
但是修改現有系統,你覺得呢?除非我是老闆,否則我單以“優雅”二字要求後端和前端去修改,可能性不大吧。


“从小的地方,这里改一点,哪里推进一下。当真的要推一个重新设计的时候,你会发现这时就不这么难了。”
這句話,我以前一直都相信。
但是往往是,“这里改一点,哪里推进一下”,最後出 BUG 了,然後修復後整條業務線平靜下來,我得到的只是罵名。
(*說句題外話,曾經試過,幫別人修改一下 HTML 靜態文件,然後過了兩天,對方 oracle 掛了,對方運維排障,前 2 天有人改過東西。嗯沒錯,這鍋最後我背了,後面排查是因為 listen log 超 2G 的原因,但也不重要了,反正鍋已經牢牢扣我身上)
hantsy
2020-01-03 17:55:30 +08:00
究竟怎样的 API 才符合真正的 REST 风格,估计一百人有一百个不同的说法。

Fielding 博士的论文被认为是 REST 的定义,后来又有了 Richardson 成熟度模型来判定 REST 规范级别(主要针对 HTTP 协议, REST 不局限于 HTTP )。REST 约定只是提出一些 API 设计建议,让它看起来更符合 HTTP 语义,说白了,就是用 HTTP 协议最自然的方式表达出来。

GET /posts?type 全部 POSTs,支持 Type 过滤,返回 200
GET /posts/{id} 通过 ID 查询单个 POST,返回 200 或者 404
POST /posts 创建新 POST, 返回 201,Location 指向新建的资源 URI
PUT /posts/{id} 更新某个 POST, 返回 204 (或者 404 )
DELETE /posts/{id} 删除某个 POST, 返回 204 (或者 404 )



1. URI 表示资源或者资源的集合。
2. HTTP Method 表示行为,而不是放到 URI 中去。
3. 返回使用 HTTP Status 表示返回状态。

[不要太纠结 HTTP 规范,如果按规范 PUT 也可以新建,PATCH 用于更新操作更适合,JSON Patch 才是更新理想格式]

有人说 REST API 麻烦,我一直不解。难道用一些毫无规律的 API,加上一些狗屁不通的 API 文档就是最好的方式。有人还搬上什么大厂的什么服务了多少 XXX 来作证,也太奇葩了吧,这跟讨论 API 设计的优劣有什么关系。
hantsy
2020-01-03 17:58:52 +08:00
@enjoyCoding 这一点没错,但是

1. 设计时可以考虑的是,并不是所有资源都有 DELETE 操作。
2. 一些 DELETE 操作可能转化为 Soft Delete,即更新数据库中删除标志位。
laravel
2020-01-03 18:10:47 +08:00
一个人想怎么搞都行,团队那就要折中了,比如增加的工作量 和 增加新的东西带来的不适感,你觉得好,别人觉得一般。
index90
2020-01-03 18:14:41 +08:00
@hantsy 什么叫做烂?什么叫做好?评价标准是什么?
只用 POST/GET 就叫做烂了?用 POST/GET/PUT/DELETE 就叫做好了?
只要遵循 REST 就叫做好了?那么怎样才遵循 REST 呢?能用上 PUT 和 DELETE 就叫遵循了?
LZ 例子:“获取对应学期下评语:[get] /back/remark/{termId} 删除数据:[delete] /back/record/{recordId}”
这叫遵循 REST 了?资源描述清晰么? URL 设计合理么?

脱离实际问题,一直在自己有限的认知领域里纠结,转圈圈,正如楼上有人说的:“非要把 restful 当成圣经一样是不是傻?搞得自己弄个 restful 就高人一等一样。”

REST 还要求面向资源设计 path
究竟是:
/brand/{brand_id}/reseller/{seller_id}/car/{car_id}
还是:
/reseller/{seller_id}/brand/{brand_id}/car/{car_id}
还是:
/car/{brand_id}/{seller_id}/{car_id}
更好呢?
如果我要取消一个订单,究竟有 PUT,还是 PATCH,还是 POST,还是 DELETE 呢?
哪个才是好,哪个才是烂呢?如果这个是公开 API,那么请问业界用哪个作为标准呢?

规范,是用来降低沟通理解成本的。抱紧 REST 圣经,忘了本来的目的。
我对好的公开 API 的定义是,我只要看懂其中一两个 API,其他 API 我都基本能看懂了。

PS:proto 定义接口了解下,REST 不是唯一的出路。
hantsy
2020-01-03 18:29:29 +08:00
@index90 嗯,“规范,是用来降低沟通理解成本的”这个没错。

我不懂了,是能用 PUT,DELETE 表达的地方为什么不用呢?我有说过所有地方都要刻意套用 PUT,DELETE 吗?

Proto 只是在传输方式或格式上作文章,不是 REST 对立和竞争的。在系统内部嘛,太多的东西可以选择,基于 message 方式几乎我能用上就用了。

那么在对外的 API 上,你能告诉是大家愿意接受 REST,还是 Proto ?我是没有用在外部暴露 API 时用过 Proto 了,请示例一下。

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

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

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

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

© 2021 V2EX