在查询字符串或请求正文中包含数据的 Restful URL?

发布于 2024-08-08 15:46:13 字数 356 浏览 6 评论 0原文

在查询字符串和请求正文中的 REST URL 中传递数据的经验法则是什么?

即:您正在创建一项添加曲棍球运动员的服务。您可以使用:

PUT /players 
{ "name": Gretzky }

或者

PUT /players?name=Gretzky

如果您要传递大量数据,则需要使用选项 #1,因为 URL 长度有限制。但除此之外,为什么不直接使用查询字符串来传递数据呢?


更新:删除了您可以在浏览器中测试选项 #2 的评论。意识到(废话)你只能在浏览器中执行 GET-s。

What's the rule of thumb for passing data in a REST URL in the query string vs. the body of a request?

Ie: You're creating a service to add hockey players. You could go with:

PUT /players 
{ "name": Gretzky }

or

PUT /players?name=Gretzky

If you're passing a lot of data, you would need to go with option #1 as there is a limit on the URL length. But other than this, why not just use the query string to pass data?


Update: Removed comment that you could test option #2 in a browser. Realized (duh) that you can only do GET-s in your browser.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

败给现实 2024-08-15 15:46:13

根据 HTTP 的 PUT 定义,您的第一个请求是使用仅包含一个玩家名称的新列表覆盖玩家列表。它没有添加到玩家列表中。

第二种选择对我来说并没有多大意义。在没有主体的情况下执行 PUT 与 PUT 的含义并不真正一致。

考虑到 POST 的标准定义之一是附加到现有资源,我不确定为什么你不这样做,

POST /players 
{ "name": Gretzky }

如果你确定所有玩家名称都是唯一的,那么你可以像这样使用 PUT:

PUT /player/Gretzky
{ "name": Gretzky }

当您决定在 HTTP 上执行 REST 时,您同意按照 RFC2616 中定义的方式使用 HTTP。这就是统一接口约束的含义。
顺便说一句,不存在 REST URL 这样的东西,您无法在浏览器中测试这两个选项,因为如果没有 javascript,您就无法在浏览器中执行 PUT。

Based on HTTP's definition of PUT, your first request is overwriting the list of players with a new list that contains just one player name. It is not adding to the list of players.

The second option does not really make much sense to me. Doing PUT without a body is not really consistent with the meaning of PUT.

Considering that one of the standard definitions of POST is to append to an existing resource, I'm not sure why you wouldn't do

POST /players 
{ "name": Gretzky }

If you are sure that all you player names are going to be unique then you could use PUT like this:

PUT /player/Gretzky
{ "name": Gretzky }

When you decide to do REST on HTTP you are agreeing to use HTTP in the way that is defined in RFC2616. That's what the uniform interface constraint means.
And just to be pedantic, there is no such thing as a REST URL and you can't test either option in a browser because without javascript, you can't do a PUT in a browser.

终止放荡 2024-08-15 15:46:13

选项 #1 很好,尽管可能有些过头了。选项 #1 不太很好,因为它不是幂等的。

选项 #2 是一个糟糕的想法。那将是滥用 PUT。当您的请求数据有效负载是不透明的数据块(通常是大型数据块或分层数据块)时,应主要使用 PUT。较小的、非分层的有效负载作为 POST 更有意义。

另外,尽量避免通过查询参数更改状态。如果不是 GET 请求,那么从技术上来说没有什么危险,但它并不是真正的 RESTful。

在这种情况下,您应该做的是:

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。)

编写使用更多内容的 REST Web 服务HTTP 而非 POST 和 GET 只能在阅读了 HTTP 规范之后进行。 。 (这是一本非常有用的读物​​。)如果您使用的框架可以为您做出所有决定,则该规则会有点宽松。

Option #1 is fine, though probably overkill. Option #1 is not fine because it's not idempotent.

Option #2 is a BAD idea. That would be misusing PUT. PUT should be used primarily when your request data payload is an opaque block of data, usually either large or hierarchical. Smaller, non-hierarchical payloads make more sense as POST.

Also, try to avoid changing state via query parameters. There's nothing technically dangerous about that if it's not a GET request, but it's not really RESTful.

In this case, what you should be doing is:

POST /players HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=Gretsky

This should return a 201 Created response. (There is an exception to this: If you don't create the resource immediately, and it might be rejected at a later time, use 202 Accepted instead.)

Writing a REST web service that uses more of HTTP than POST and GET should only be done after having read the HTTP specification. (It's a very useful read.) That rule is a bit looser if you're using a framework that makes all the decisions for you.

终止放荡 2024-08-15 15:46:13

我对 REST 操作的理解是 URL 唯一标识资源,而请求正文包含资源的表示。鉴于此,您的任何一个选择是否真正是 RESTful 都是值得怀疑的。

第一个是,假设资源名为“Players”,并且该资源上的 GET 返回玩家列表(我不会讨论该 GET 是否返回其他资源 URL 的问题......Fielding 会说它应该,以及获取资源数据的单独请求)。

第二种情况是,假设请求正文包含以名称“Gretsky”键入的信息。但是,这需要您在外部生成密钥。

My understanding of REST operations is that the URL uniquely identifies the resource, while the body of the request contains the representation of the resource. Given that, it's questionable whether either of your options are truly RESTful.

The first would be, assuming that the resource is named "Players" and a GET on that resource returns a list of players (I won't get into the question of whether that GET returns other resource URLs or not ... Fielding would say that it should, with individual requests to get the resource data).

The second would be, assuming that the request body contained information keyed by name "Gretsky". However, that requires you to generate the keys externally.

傾旎 2024-08-15 15:46:13

使用的 url 应通过路径组件或查询参数来标识正文中的资源,但我更喜欢使用名称或 id 之类的路径组件。身体应该是一个代表;您 PUT 应该与您从同一 url 获取的内容相同或相似(或者可以获取,在多种格式的情况下)

示例 #1 不合适,因为您将单个玩家的表示发送到所有玩家的 url 。在这种情况下,POST 会更合适。

如果扩展到所有字段,示例 #2 会稍微不合适,因为您将在 url 中发送表示数据。

The url used should identify the resource in the body, either by path components or query parameters, though I would prefer path components for something like a name or id. The body should be a representation; the one you PUT should the same or similar as what you GET from the same url (or can get, the in case of multiple formats)

Example #1 is inappropriate because you are sending a representation for a single player to a url for all players. POST would be more appropriate in this case.

Example #2 would be slightly inappropriate if extended to all fields because you would then be sending representation data in the url.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文