【问题标题】:How to be RESTful with long URLs?如何使用长 URL 实现 RESTful?
【发布时间】:2015-06-10 21:31:59
【问题描述】:

REST 架构说资源状态也应该获得一个 URL。

我正在制作一个带有非常大查询的小型应用程序。我想为每个查询生成 URL,但查询通常大于 URL 字符限制。我尝试使用 URL 缩短器,但我的 URL 对它们来说太大了。

网上很多人建议使用 POST,但这不是幂等的。我真的不想限制我的查询长度,并且 URL 应该能够识别无限量的资源。

是否有一种 RESTful 方式来解决不涉及 POST 请求的非常大的 URL?

【问题讨论】:

  • 使用PUT,至少是幂等的。唉,every abstraction is leaky.
  • ElasticSearch 通过在 GET 请求中实际包含正文来解决此类问题。不确定这是多么标准(并且一些 HTTP 客户端不会发出这样的请求),但我还没有看到 RFC 在哪里禁止它。
  • 明天我会调查你的建议。有趣的是,办公室里有人告诉我搜索与 REST 架构完全不匹配。这是有道理的,你们中的任何人都同意/不同意吗?我对 REST 很陌生,刚刚阅读了 O'Reilly 的书,我正在努力坚持下去,即使没有练习,也可以练习。
  • 我不同意。如果您将查询视为资源,则搜索可以在 REST 上建模。请看我的回答。
  • 搜索和 REST 只要您的查询相对较短和简单——或者如果您将重新运行足够长或复杂的查询以证明将它们持久化在服务器上是合理的。 (注意,重要的是 查询,而不是结果列表。短查询可以产生大量结果。)除非在服务器上持久化搜索确实有优势,否则将搜索作为资源是一种hack 让您对使用正确的动词感觉更好。作为回报,您现在可以管理另一种资源,而客户不会特别倾向于进行这种管理。

标签: rest url get


【解决方案1】:

要以 RESFtul 方式对此进行建模,请将查询视为资源。它们可以被创建、检索和最终删除。

客户端向queries 资源发出POST 请求,请求正文中包含查询详细信息。

POST /queries
Content-Type: application/json

{
  "condition1":
  {
    "on": "field1",
    "comparison": "equals",
    "value": 42
  },
  "condition2":
  {
    "on": "field2",
    "comparison": "like",
    "value": "foo%"
  }
}

这会创建一个新的查询资源。服务器将响应:

201 Created
Location: /queries/D560EC80-1006-11E5-80F6-75919330F945

路径段D560EC80-1006-11E5-80F6-75919330F945 将是服务器为此特定查询生成的ID。

然后客户端请求这个查询资源的状态。

GET /queries/D560EC80-1006-11E5-80F6-75919330F945

服务器响应查询结果。

200 OK
Content-Type: application/json

{
  "id": "D560EC80-1006-11E5-80F6-75919330F945",
  "querydetails":
  {
    "condition1":
    {
      "on": "field1",
      "comparison": "equals",
      "value": 42
    },
    "condition2":
    {
      "on": "field2",
      "comparison": "like",
      "value": "foo%"
    }
  },
  "result":
  {
    "length": 12,
    "results":
    [
      {
        // details about the first hit
      },
      // more hits
    ]
  }
}

稍后,客户端可以删除查询。

DELETE /queries/D560EC80-1006-11E5-80F6-75919330F945

或者服务器可以在一段时间后自动删除查询。

【讨论】:

  • 使用 JSON 抽象您的查询可能是一种更简单的方法,如本答案中所述。另一种方法是设计自己的查询缩短器,但必须在客户端和服务器端都实现它。
  • @kingAm 我不明白。我的答案中的 JSON 仅用于说明。这不重要。我的答案中的重要部分是使用POST 创建并使用GET 获取查询结果。
  • 我的意思是,不是将整个查询放在 URL 中,而是使用 JSON 来缩短它并将其放入 POST 请求正文中。我们可以将其视为缩短 URL 的标准方式。不是吗?对不起,如果我没有任何意义。可能是我在错误的上下文中看到了这个问题。
  • 你是对的,我将查询的详细信息放在 POST 请求的正文中,而不是放在 GET 请求的 URL 中。这是可能的,因为我认为查询是一种资源。 REST 是关于资源的,而不是 RPC。
  • 太棒了,现在我完全理解了。作为一个附带问题,POST 既不安全,也不幂等。如果我们使用 POST 进行查询,这不被认为是不好的做法。(尽管我在这种情况下看到了为什么我们需要这样做)
【解决方案2】:

Lutz Horn 回答得非常好。但是很有可能客户端可能不希望进行三个 api 调用 - 一个创建查询响应,第二个获取它,第三个删除它。

如果您确定您的查询长度将保持小于 8 KB(这是大多数网络服务器获取查询长度的限制),请继续 GET 请求。 此外,如果您对缓存不感兴趣,请使用 post,如果您清楚后果,偶尔忽略 REST 也没有错。

【讨论】:

  • “如果你清楚后果,偶尔忽略 REST 并没有什么错。”但不要将结果称为 RESTful。
  • 我完全同意你的观点,我希望这个论点足以说服客户以其他方式使用它。但有时很难说服客户发出三个 http 请求,在非休息情况下一个就足够了。我本人曾与客户发生过很多争论,他们试图避免做一些不“安宁”的事情,但大多数时候你必须给出强有力的论据来支持。
猜你喜欢
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 2014-01-08
  • 2016-03-10
  • 2014-04-23
相关资源
最近更新 更多