jasonyang9
V2EX  ›  PHP

REST API 中,同一个参数多个值,正确的传递姿势是怎样的?

By jasonyang9 at 2018 年 9 月 13 日 · 11091 次点击

比如要获取 2 本书的信息:

GET http://server/books?id=1001&id=1002
GET http://server/books?id=1001,1002
GET http://server/books/1001/1002           这个肯定不对了

当然用 POST 配合 JSON 值过去应该是不符合语义的。

所以正确的姿势是怎样的?服务器端又应该如何获取这些值?

41 条回复  •  2018-09-26 16:45:51 +08:00
syh
   1
syh  
   2018 年 9 月 13 日
试下这样 http://server/books?id=1001_1002
mnssbe
   2
mnssbe  
   2018 年 9 月 13 日
id 放个 json
Mutoo
   3
Mutoo  
   2018 年 9 月 13 日   ❤️ 1
?ids[]=1001&ids[]=1002
lazypu
   4
lazypu  
   2018 年 9 月 13 日   ❤️ 1
?id[]=1&id[]=2
l12ab
   5
l12ab  
   2018 年 9 月 13 日 via iPhone
id[]=1001,1002
ChoateYao
   6
ChoateYao  
   2018 年 9 月 13 日   ❤️ 1
如果是 PHP 的话,直接使用 id[]=1&id[]=2 即可。
l12ab
   7
l12ab  
   2018 年 9 月 13 日 via iPhone   ❤️ 1
不好意思,打错了,正确的见 3 楼 4 楼
chinvo
   8
chinvo  
   2018 年 9 月 13 日 via iPhone
符合 http 的用数组,或者用逗号分隔
tanszhe
   9
tanszhe  
   2018 年 9 月 13 日
ids=[1,2,3,4,5,34,……]
broadliyn
   10
broadliyn  
   2018 年 9 月 13 日   ❤️ 1
ids=1,2,3,4 不就好了。
Restful Api 只是一种 Api 风格,不是强制规范。你完全可以选择性选择自己觉得有用的建议风格。
没必要奉为圭臬。
Mutoo
   11
Mutoo  
   2018 年 9 月 13 日   ❤️ 1
@Mutoo 这种写法的 querystring,PHP 可以直接支持,但并没有出现在任何的 RFC 规范中,其它语言的后端需要自行解析。
gouflv
   12
gouflv  
   2018 年 9 月 13 日 via iPhone
GET http://server/books/1001,1002
fighterlyt
   13
fighterlyt  
   2018 年 9 月 13 日
url 长度是有限的,而参数是无限的,所以出现在 URL 中的批量参数,都是有局限的
gaius
   14
gaius  
   2018 年 9 月 13 日   ❤️ 1
前两种就是 int[]接收
stzz
   15
stzz  
   2018 年 9 月 13 日   ❤️ 2
我来个绝对 restful 的方法,
请求两次
GuryYu
   16
GuryYu  
   2018 年 9 月 13 日   ❤️ 5
POST http://server/books/list
Body 里面用 JSON 传过滤参数
可以理解成创建一个 books 的临时列表资源, 列表的过滤参数来自 BODY, 并直接返回该资源
ylcc
   17
ylcc  
   2018 年 9 月 13 日
三个字,随便弄,只要你的后端能解析
fighterlyt
   18
fighterlyt  
   2018 年 9 月 13 日
@GuryYu 看了这个多回复,只有你的说法还是比较合理的,其他都完全不考虑 URL 长度问题
vicvinc
   19
vicvinc  
   2018 年 9 月 13 日
/books?include=author&book[]=1001,1002
vicvinc
   20
vicvinc  
   2018 年 9 月 13 日
@l12ab 正解
90safe
   21
90safe  
   2018 年 9 月 13 日
无论是 POST 还是 GET,都可以用:id[]=1&id[]=2 这样的类型传递。也可以:id=1001,1002 然后接收端分割成数组。
jasonyang9
   22
jasonyang9  
OP
   2018 年 9 月 13 日
多谢各位。我再捣鼓捣鼓
zhzer
   23
zhzer  
   2018 年 9 月 13 日 via Android
随便选个分隔符不就完事?
isayme
   24
isayme  
   2018 年 9 月 13 日
有的服务端支持 id=1001&id=1002, 有的支持 id[]=1001&id[]=1002, 也有的都支持.
主要是看你们服务端的支持情况.
http://httpbin.org/get?a=1&a=2&b[]=3&b[]=4
https://httpbin.isayme.org/anything?a=1&a=2&b[]=3&b[]=4

或者直接改用 POST 方法?
fighterlyt
   25
fighterlyt  
   2018 年 9 月 13 日
@jasonyang9 别听那伙人瞎比比,URL 长度的限制必须考虑,所以最安全的方法就是 POST
shakaraka
   26
shakaraka  
   2018 年 9 月 13 日
?id=1001,1002
jowan
   27
jowan  
   2018 年 9 月 13 日
rogwan
   28
rogwan  
   2018 年 9 月 13 日 via Android
一般的做法是逗号分隔
SorcererXW
   29
SorcererXW  
   2018 年 9 月 13 日
一般来说用逗号分隔问题不大, 比如 stackexchange 的 api 设计: https://api.stackexchange.com/docs/answers-by-ids
也可以考虑 http batch requests, 可以参考看看 facebook 的 api: https://developers.facebook.com/docs/graph-api/making-multiple-requests
jingniao
   30
jingniao  
   2018 年 9 月 13 日 via Android
一直是逗号分隔
Raymon111111
   31
Raymon111111  
   2018 年 9 月 13 日
就是 list 啊
Leammin
   32
Leammin  
   2018 年 9 月 13 日 via Android
@GuryYu 老哥你解决了我困扰已久的问题!
Leammin
   33
Leammin  
   2018 年 9 月 13 日 via Android
@GuryYu 不过 delete 要怎么办
metamask
   34
metamask  
   2018 年 9 月 14 日
python -- django

GET http://server/books?id=1001,1002

id = "1001, 1002"
id = id.split(",")

>>> ['1001', ' 1002']
skinny
   35
skinny  
   2018 年 9 月 14 日
@Leammin 你都用了 RESTFUL,难道还用 POST 删除? DELETE 请求被你吃了?
corningsun
   36
corningsun  
   2018 年 9 月 14 日
Swagger UI 自动生成的是 第一种
第二种 URL 长度明显更短

后端 Java Spring 的话,第一种和第二种都是支持的。
oongxx
   37
oongxx  
   2018 年 9 月 14 日
如果你的 API 用了 OData 规范,那就用 http://host/service/Products?$filter=Name in ('Milk', 'Cheese')

https://stackoverflow.com/questions/7745231/odata-where-id-in-list-query
wizardoz
   38
wizardoz  
   2018 年 9 月 14 日
我想知道为啥会出现要用两个 id 来取两本书这种需求?
id 自然不是随便来的,比如 mike 收藏的两本书,那就用
http://server/books?favor_by=mike
来过滤啊。
JamesC
   39
JamesC  
   2018 年 9 月 14 日
个人的做法是 /api/resources/(1,3,5,7)
其实重点在于做好 API 接收解析,id 之间分隔的规范.
直接获取是不现实的.如何编写符合 Restful 原则的规范才重要.
又或者 /api/resources?ids=1,3,5,7 也是可以的,路径要清晰,意义明显.
ps:既然选择了 Restful 的设计思路就尽量符合规范.
Leammin
   40
Leammin  
   2018 年 9 月 14 日 via Android
@skinny ?我说的就是 delete 啊,我意思是批量删除要怎么操作。
yc8332
   41
yc8332  
   2018 年 9 月 26 日
只能传字符串啊。。。至于形式,看你喜欢啊
© 2026 V2EX · 88ms · 3.9.8.5