在查询字符串中的REST URL中传递数据与请求正文之间的经验法则是什么?
是的:你正在创建一个添加曲棍球运动员的服务。你可以选择:PUT /players
{ "name": Gretzky }
或
PUT /players?name=Gretzky
如果您传递了大量数据,则需要使用选项#1,因为URL长度有限制。但除此之外,为什么不使用查询字符串来传递数据?
更新:删除了您可以在浏览器中测试选项#2的评论。实现(呃)您只能在浏览器中执行GET-。
答案 0 :(得分:31)
根据HTTP对PUT的定义,您的第一个请求是使用仅包含一个玩家名称的新列表覆盖玩家列表。它没有添加到玩家列表中。
第二种选择对我来说并没有多大意义。没有身体做PUT与PUT的含义并不完全一致。
考虑到POST的标准定义之一是附加到现有资源,我不确定你为什么不这样做
POST /players
{ "name": Gretzky }
如果您确定所有玩家名称都是唯一的,那么您可以像这样使用PUT:
PUT /player/Gretzky
{ "name": Gretzky }
当您决定在HTTP上执行REST时,您同意以RFC2616中定义的方式使用HTTP。这就是统一接口约束的含义。 只是为了迂腐,没有REST URL这样的东西,你不能在浏览器中测试任何一个选项,因为没有javascript,你就无法在浏览器中进行PUT。
答案 1 :(得分:3)
选项#1很好,但可能有点过分。选项#1 不很好,因为它不是幂等的。
选项#2是 BAD 的想法。这将是滥用PUT。当您的请求数据有效负载是不透明的数据块(通常是大数据层或分层数据块)时,主要应使用PUT。较小的非分层有效载荷更有意义,因为POST。
另外,尽量避免通过查询参数更改状态。如果它不是GET请求,那么在技术上没有任何危险,但它并不是真正的REST。
在这种情况下,您应该做的是:
POST /players HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
name=Gretsky
这应该返回201 Created
响应。 (有一个例外:如果您不立即创建资源,以后可能会被拒绝,请改用202 Accepted
。)
编写一个使用HTTP而不是POST和GET的REST Web服务只能在读完HTTP specification之后完成。 (这是非常有用的阅读。)如果您使用的框架可以为您做出所有决定,那么该规则会更宽松。
答案 2 :(得分:2)
我对REST操作的理解是URL唯一地标识资源,而请求的主体包含资源的表示。鉴于此,您的任何一个选项是否真的是RESTful都是值得怀疑的。
第一个是,假设资源被命名为“Players”并且该资源上的GET返回一个玩家列表(我不会讨论GET是否返回其他资源URL的问题......菲尔丁会说,应该根据个人请求获取资源数据。
第二个是,假设请求正文包含以名称“Gretsky”键入的信息。但是,这需要您在外部生成密钥。
答案 3 :(得分:-2)
使用的url应该通过路径组件或查询参数来标识正文中的资源,尽管我更喜欢路径组件,例如名称或id。身体应该是一种表现形式;您PUT应该与您从同一个网址获取的内容相同或相似(或者可以获得,如果是多种格式)
示例#1不合适,因为您要将单个玩家的表示发送给所有玩家的网址。在这种情况下,POST会更合适。
示例#2如果扩展到所有字段会稍微不合适,因为您将在网址中发送表示数据。