dunhanson
V2EX  ›  程序员

RESTFul API 接口规范, GET 请求如何传递复杂对象?

By dunhanson at 2022 年 6 月 17 日 · 9065 次点击

感觉进入了死胡同了

GET 用于查询,POST 用于创建,GET 传递 body 不符合规范

第 1 条附言  ·  2022 年 6 月 17 日
还有一个参数命名规范,是驼峰还是下划线?单词之间
第 2 条附言  ·  2022 年 6 月 18 日
准备复杂的查询还是用 Post
72 条回复  •  2023-05-27 09:20:24 +08:00
TWorldIsNButThis
   1
TWorldIsNButThis  
   2022 年 6 月 17 日 via iPhone   ❤️ 3
规范没限制 get 传 body
只是一些框架不支持
dzdh
   2
dzdh  
   2022 年 6 月 17 日   ❤️ 5
![]( )
wolfie
   3
wolfie  
   2022 年 6 月 17 日
get 没 body
dingyaguang117
   4
dingyaguang117  
   2022 年 6 月 17 日
GET 传 body 有很多隐患。 要考虑整个链路上的库是否都支持。只要有一环不支持,就麻烦得很。

感觉直接参数 base64 一下放到 querystring 好点
dunhanson
   5
dunhanson  
OP
   2022 年 6 月 17 日
@TWorldIsNButThis 有一些文章又说规范不建议,感觉都摸棱两可
dunhanson
   6
dunhanson  
OP
   2022 年 6 月 17 日
@dingyaguang117 是可以这样子,但是好麻烦,也不直观
qunqun
   7
qunqun  
   2022 年 6 月 17 日 via Android
post 一个 task, 然后 get 取结果 ?
DoveAz
   8
DoveAz  
   2022 年 6 月 17 日
@TWorldIsNButThis chrome 都不支持,这直接没得玩
ktqFDx9m2Bvfq3y4
   9
ktqFDx9m2Bvfq3y4  
   2022 年 6 月 17 日 via iPhone
所以有时候不需要完全按 restful 来。比如你有一个接口用来验证订单是否可提交,传的参数会很多,post 更合适。
Trim21
   10
Trim21  
   2022 年 6 月 17 日
太过复杂就不用 rest 了呗。restful 本来就是为了方便理解 api 的,最后搞的又不直观又难用就本末倒置了。
dunhanson
   11
dunhanson  
OP
   2022 年 6 月 17 日
@qunqun 这个增加工作量吧
dunhanson
   12
dunhanson  
OP
   2022 年 6 月 17 日
@Trim21 现在进退两难
beginor
   13
beginor  
   2022 年 6 月 17 日 via Android
大对象用 post 吧,post 也属于 rest 吧
eason1874
   14
eason1874  
   2022 年 6 月 17 日
这才多长,才几百字节,放 URL 没问题啊,连最落后的 IE 也支持 2K 长度 URL

二维展开到一维就好了,比如 searchWord=&areaProvince=&areaCity=,懒得处理就直接 area=encodeURIComponent(data json)
xuelu520
   15
xuelu520  
   2022 年 6 月 17 日
base64 传过去呗。确实需要用 get 只能考虑改下接口参数,自己解析。
另外规范灵活一点,改成 post 的
ktqFDx9m2Bvfq3y4
   16
ktqFDx9m2Bvfq3y4  
   2022 年 6 月 17 日 via iPhone
op 如果过于较真的话,那么 OCR 识别接口是不是应该使用 get ?然后你 get 传一张图片是不是更难了哈,这样真变成为了 restful 而 restful 了。
cpstar
   17
cpstar  
   2022 年 6 月 17 日
OP 的确进入一个死胡同了,这个 searchCondition 不能这么弄
如果严格 RESTful ,那应该 GET /search/{searchWord}/{area}/{channel}/{pageSize}/...
该这么整么?显然不是啊,search 以及带有 searchCondition 的,并不是严格遵从 RESTful ,RESTful 可以理解对实体的,比如 GET /product/{id},
dunhanson
   18
dunhanson  
OP
   2022 年 6 月 17 日 via iPhone
@Chad0000 这种属于 POST 吧?
dunhanson
   19
dunhanson  
OP
   2022 年 6 月 17 日 via iPhone
@xuelu520 最早用的这种,但是不直观
dunhanson
   20
dunhanson  
OP
   2022 年 6 月 17 日 via iPhone
@eason1874 在想有没有其他更好的方式
XCFOX
   21
XCFOX  
   2022 年 6 月 17 日
GraphQL 解君愁
dcsuibian
   22
dcsuibian  
   2022 年 6 月 17 日
POST /search-results
POST 是新建资源,“搜索”不能作为一种资源,但“搜索结果”呢?
knives
   23
knives  
   2022 年 6 月 17 日
可以用 Content-Type 区分。POST application/json 为创建,POST application/x-www-form-urlencoded 为查询
oxromantic
   24
oxromantic  
   2022 年 6 月 17 日
你这个业务场景就是创建啊,创建一个查询结果集
jorneyr
   25
jorneyr  
   2022 年 6 月 17 日
JSON Base64 编码一下,作为一个 URL Query 参数传给后端。
imycc
   26
imycc  
   2022 年 6 月 17 日
执着于 RESTFul 的话,那就是用 POST 创建一个查询请求,返回的就是查询请求的结果。(是不是很合理)
不执着于 RESTFul 的话,GET 的 querystring 里面直接塞一段 json 字符串。之前用 steam 的 API ,他们就是这么干的
version0
   27
version0  
   2022 年 6 月 17 日
不用纠结 restful 啦,以前我也纠结,直到我看到了一些出名的工具咋查询的,比如 elasicSearch
chendy
   28
chendy  
   2022 年 6 月 17 日
直接 POST /xxx/_search
规范是死的,人是活的
Opportunity
   29
Opportunity  
   2022 年 6 月 17 日   ❤️ 1
POST /xxx
X-HTTP-Method-Override: GET

{ }

按照 REST 规范应该是这么搞,尤其是有些代理服务器对 DELETE 之类方法支持不好的时候

IBM 用的 x-method-override
pengtdyd
   31
pengtdyd  
   2022 年 6 月 17 日
@chendy 同意!规范是死的,如果 java 都按照阿里的 java 开发手册来,那估计大部分项目都要重构了
sujin190
   32
sujin190  
   2022 年 6 月 17 日 via Android
@TWorldIsNButThis 绝大部分库和软件的实现才叫规范,写在纸上的可不叫规范,别说其他了,浏览器估计都不支持 get 传 body
ijse
   33
ijse  
   2022 年 6 月 17 日
可以用 tj 的 npm 包:
https://www.npmjs.com/package/qs

nodejs 官方文档有介绍,这种基本算规范了吧
https://nodejs.org/api/querystring.html
kytrun
   34
kytrun  
   2022 年 6 月 17 日
本质还是强迫症导致的。这么看:符合规范时你的接口叫 RESTful ,不符合规范叫接近 RESTful ,为了高效率工程化做出取舍,达到最佳状态,没毛病
comoyi
   35
comoyi  
   2022 年 6 月 17 日
进死胡同了就换大路走
规范并不一定就是好的,一个规范不好用的时候就使用其他规范。
之前也纠结过,多层级的参数该 POST 还是得用
dr1q65MfKFKHnJr6
   36
dr1q65MfKFKHnJr6  
   2022 年 6 月 17 日
emmm, 我在想,非得明文嘛, 直接参数格式化转 base64 ,后台在解一下。
iseki
   37
iseki  
   2022 年 6 月 17 日 via Android
别让自己难受…规范不合适的时候就别按规范做了
lovedebug
   38
lovedebug  
   2022 年 6 月 17 日
参考微软,谷歌规范,这一类情况应该用 POST, 微软和谷歌针对复杂情况扩展了 RESTful 方案
类似 POST /v1/logs/:search Req Body {} 这样做适合你的情况,Path 最后是一个动作
cutchop
   39
cutchop  
   2022 年 6 月 17 日
我所有请求都用 POST
dunhanson
   40
dunhanson  
OP
   2022 年 6 月 17 日
@chendy 以前就是这样,想改变下
dunhanson
   41
dunhanson  
OP
   2022 年 6 月 17 日
@cedoo22 确实可以这样,以前也这么干过,但是不直观这种,想要看细节,还要 base decode 一下
dunhanson
   42
dunhanson  
OP
   2022 年 6 月 17 日
@version0 是的,ES 这个问题我看别人在 github 的 issue 上面都吐槽了。
dunhanson
   43
dunhanson  
OP
   2022 年 6 月 17 日
@XCFOX 估计普及没那么快
dunhanson
   44
dunhanson  
OP
   2022 年 6 月 17 日
@kytrun
@comoyi
@iseki 哈哈哈 准备复杂查询用 POST 了
Jooooooooo
   45
Jooooooooo  
   2022 年 6 月 17 日
都扔进 post 的 body 里呀.

你这这么复杂的请求体, 还强行用 get 要不得.
Felldeadbird
   46
Felldeadbird  
   2022 年 6 月 17 日
复杂体不要用 GET 。 或者将上面的 value 数值化,就是调试问题变得可读性奇差。
AV1
   47
AV1  
   2022 年 6 月 17 日
写在 body 不行,那就写在 http header 里面。
可以把对象 base64 之后,写在自定义的请求报头里面(认真
leon0318
   48
leon0318  
   2022 年 6 月 17 日 via iPhone
@XCFOX 这都不是一个维度的东西……
GeruzoniAnsasu
   49
GeruzoniAnsasu  
   2022 年 6 月 17 日
你的接口是一个动作语义


你已经不 restful 了


趁早放弃残废的 restful 开始 post 一把梭还有救



你可以美其名曰 lite-json-rpc
Rocketer
   50
Rocketer  
   2022 年 6 月 17 日 via iPhone
又见 RESTful 八股文。

RESTful 根本没有确定的标准,只是一个大概的方向。你死抠细节……哪有细节让你抠?

所以大概方向对,团队内部统一,好使,就行了。
terranboy
   51
terranboy  
   2022 年 6 月 17 日
qs 能行吗
dddd1919
   52
dddd1919  
   2022 年 6 月 18 日
参考 ElasticSeach 的结构化查询:
POST /resources/_search
sneezry
   53
sneezry  
   2022 年 6 月 18 日
看其实这是个 query API ?为什么要设计成 GET 啊,是有什么限制吗
hhyyd
   54
hhyyd  
   2022 年 6 月 18 日
碰到过类似问题。我们当时的方案

有直接用 get 传 body (楼上说可能有问题,这个我没碰到不清楚);

也有直接拼 query ,虽然不好看但是容量限制很大,一般超不了;

还有就是用 post ,个别复杂搜索接口用 post ,毕竟规矩是死的,人是活的,不要被限制死。
guoqiao
   55
guoqiao  
   2022 年 6 月 18 日
方法 1: 参数结构不要嵌套, 然后 url 参数是可以重复的,比如 /search?city=广州&city=深圳. 当然后端需要正确的解析.
方法 2: GET 可以带 body, 相应的, 只要你的后端去读取 body 并解析就行了.
方法 3: 用 POST, 代码的首要意义在于实现功能, 不必拘泥于繁文缛节.
xuanbg
   56
xuanbg  
   2022 年 6 月 18 日
@Chad0000 OCR 这个要先 POST 传图创建一个任务,然后根据返回的 id 把识别出来的内容 GET 回来啊。。。狗头保命。

不过 OCR 还真的需要这样,这并不是为了 restful ,而是异步任务可以提高效率。
yueye115
   57
yueye115  
   2022 年 6 月 18 日
@dingyaguang117 正解, query 有长度限制, 而且 query 都是字符串, 没有其他类型吧. http 就是这么设计的, 你非要传个复杂对象去查, 只能说你就不符合 http 的规范.
dunhanson
   58
dunhanson  
OP
   2022 年 6 月 18 日
@GeruzoniAnsasu
@Rocketer
@hhyyd
@guoqiao 准备改成复杂的查询用 POST
liyunlong41
   59
liyunlong41  
   2022 年 6 月 18 日 via iPhone
我也遇到过这种,批量查询的 API ,uid 可能有几千个,直接用了 post
dingyaguang117
   60
dingyaguang117  
   2022 年 6 月 18 日
POST 有个问题是你这个查询链接就不可以分享了
leoleoasd
   61
leoleoasd  
   2022 年 6 月 18 日
这类查询,可以视为『创建一个查询请求』,用 POST 也合理
LeegoYih
   62
LeegoYih  
   2022 年 6 月 18 日
业务项目就不要考虑完美 restful 了
bxb100
   63
bxb100  
   2022 年 6 月 18 日
graphql 适合你
saltbo
   64
saltbo  
   2022 年 6 月 18 日
restful 是要在接口设计时就要按照规范来。也就是说 api 描述的是资源,不是动作,不是业务逻辑。你这接口 search 明显是个动作,直接就不符合 restful 规范,所以就别提 GET 不能传递复杂参数了。

如果你这么设计 api ,就不要说什么 restful 了。或者自己定规范,或者用 GraphQL 。
cheng6563
   65
cheng6563  
   2022 年 6 月 18 日
@xuanbg 但是类似 webhook ,就是长时间阻塞请求当异步回调用的。。。
Torpedo
   66
Torpedo  
   2022 年 6 月 18 日
协议是不限制的,基本框架都可以。主要是浏览器的 get 不支持 body 。

另外,按照 restful 写业务的,基本都妥协的挺多的
evan1024
   67
evan1024  
   2022 年 6 月 18 日 via Android
推荐先拿一个标准比如 openapi3 swagger2 定义
fuxinya
   68
fuxinya  
   2022 年 6 月 18 日 via Android   ❤️ 1
es 的查询请求就是传的 body ,而且是 get 请求
erquiasz0825
   69
erquiasz0825  
   2022 年 6 月 19 日
@TWorldIsNButThis 对,GET 方法没有规定说不能传 body ,但前端有些框架不支持,我之前也遇到过,就约定用 post 了。

看到 elastic 官方文档对这个问题也有讨论:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_empty_search.html
erquiasz0825
   70
erquiasz0825  
   2022 年 6 月 19 日
@fuxinya 根据 elastic 文档的说法,他们其实更倾向于 GET ,但由于某些框架不支持,所以同时支持 POST ,见楼上的链接
dalianliyan
   71
dalianliyan  
   2022 年 6 月 20 日
odata
veike
   72
veike  
   2023 年 5 月 27 日
@cpstar GET /search/{searchWord}/{area}/{channel}/{pageSize}/,这种风格明显和 restful api 风格不符合,searchCondition 是规范里有明确提到?
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
© 2026 V2EX · 158ms · 3.9.8.5