REST API至少可以通过两种方式获取参数:
作为URL路径的一部分(即/api/resource/parametervalue
)
作为查询参数(即/api/resource?parameter=value
)
这里的最佳做法是什么?是否有任何一般指导原则何时使用1以及何时使用2?
真实世界的例子:Twitter使用查询参数来指定间隔.(http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321
)
将这些参数放在URL路径中会被认为是更好的设计吗?
如果有记录的最佳实践,我还没有找到它们.但是,这里有一些我在确定将参数放入url的位置时使用的指南:
可选参数往往更容易放入查询字符串中.
如果要在参数值与现有资源不对应时返回404错误,那么我会倾向于路径段参数.例如/customer/232
,232不是有效的客户ID.
但是如果你想返回一个空列表,那么当找不到参数时,我建议使用查询字符串参数.例如/contacts?name=dave
如果参数影响URI空间的整个子树,则使用路径段.例如语言参数 /en/document/foo.txt
与/document/foo.txt?language=en
我更喜欢将唯一标识符放在路径段而不是查询参数中.
URI的官方规则可在此RFC规范中找到.此处还有另一个非常有用的RFC规范,它定义了参数化URI的规则.
迟到的答案,但我会对已经分享的内容添加一些额外的见解,即请求有几种类型的"参数",你应该考虑到这一点.
定位器 - 例如ID或动作/视图等资源标识符
过滤器 - 例如,提供搜索,排序或缩小结果集的参数.
状态 - 例如会话标识,api密钥,whatevs.
内容 - 例如要存储的数据.
现在让我们来看看这些参数可能出现的不同位置.
请求标头和Cookie
URL查询字符串("GET"变量)
网址路径
正文查询字符串/多部分("POST"变量)
通常,您希望在标头或cookie中设置State,具体取决于它的状态信息类型.我想大家都同意这一点.如果需要,请使用自定义http标头(X-My-Header).
类似地,Content只有一个位置,它位于请求体中,可以是查询字符串,也可以是http multipart和/或JSON内容.这与您向服务器发送内容时从服务器收到的内容一致.所以你不应该粗鲁,做不同的事情.
诸如"id = 5"或"action = refresh"或"page = 2"之类的定位器作为URL路径是有意义的,例如mysite.com/article/5/page=2
,部分地你知道每个部分应该是什么意思(诸如文章和基础之类的基础知识) 5显然意味着获取id为5)的类型文章的数据,并将其他参数指定为URI的一部分.它们可以是形式page=2
,或者page/2
如果您知道在URI中的某个点之后"文件夹"是成对的键值.
过滤器始终位于查询字符串中,因为虽然它们是查找正确数据的一部分,但它们仅用于返回定位器单独返回的子集或修改.mysite.com/article/?query=Obama
(子集)中的搜索是过滤器,因此/article/5?order=backwards
(修改).想想它的作用,而不仅仅是它的名称!
如果"view"确定输出格式,那么它是一个filter(mysite.com/article/5?view=pdf
),因为它返回找到的资源的修改,而不是在我们想要的资源上查找.如果它决定我们看到的文章的哪个特定部分(mysite.com/article/5/view=summary
)那么它就是一个定位器.
请记住,缩小一组资源正在过滤.找到资源中特定的内容是找到... duh.子集过滤可以返回任意数量的结果(甚至为0).定位将始终找到某个特定的实例(如果存在).修改过滤将返回与定位器相同的数据,但修改后(如果允许这样的修改).
希望这有助于给人们一些尤里卡时刻,如果他们已经迷失了关于放东西的地方!
这取决于设计.REST over HTTP没有URI规则(主要的是它们是唯一的).通常它涉及品味和直觉......
我采取以下方法:
url path-element:资源及其path-element形成目录遍历和子资源(例如/ items/{id},/ users/items).当不确定问你的同事时,如果他们认为遍历并且他们认为在"另一个目录"中最可能的路径元素是正确的选择
url参数:当没有真正的遍历时(具有多个查询参数的搜索资源是一个非常好的例子)
IMO参数应该更好作为查询参数.url用于标识资源,而添加的查询参数用于指定所需资源的哪个部分,资源应具有的任何状态等.
根据REST实现,
1)路径变量用于对资源的直接操作,如联系人或歌曲ex ..
GET etc/api/resource/{songid}或
GET etc/api/resource/{contactid}将返回相应的数据.
2)查询perms /参数用于直接资源,如歌曲的元数据ex ..,GET/api/resource/{songid}?metadata = genres它将返回该特定歌曲的流派数据.
"打包"并根据universe-resource-locator提供的"上下文"POST您的数据,这意味着#1为定位器.
注意#2的局限性.我更喜欢POST到#1.
注意:讨论了限制
POST in POST参数内容是否有最大大小?
GET in GET请求的长度是否有限制?和_GET中URL参数的最大大小
ps这些限制基于客户端功能(浏览器)和服务器(配置).
根据URI标准,路径用于分层参数,查询用于非分层参数.OFC.对你来说,层次结构可能是非常主观的.
在将多个URI分配给同一资源的情况下,我喜欢将参数(识别所必需的)放入路径中,并将构建表示所需的参数放入查询中.(对我来说这样更方便.)
例如:
/users/123
和 /users/123?fields="name, age"
/users
和 /users?name="John"&age=30
对于map reduce我喜欢使用以下方法:
/users?name="John"&age=30
/users/name:John/age:30
因此,您(和您的服务器端路由器)如何构建您的URI真的取决于您.
注意:提到这些参数只是查询参数.所以你真正在做的是定义一个简单的查询语言.通过复杂的查询(包含像和,或大于等的运算符),我建议您使用现有的查询语言.URI模板的功能非常有限......