【问题标题】:Elasticsearch truly RESTful?Elasticsearch 真的是 RESTful 的吗?
【发布时间】:2018-02-10 16:43:33
【问题描述】:

我正在设计一个需要接受大量数据才能返回资源的 API。我考虑过使用 POST 请求而不是 GET,这样我就可以通过请求传递正文。在 REST 社区中,这在很大程度上是不受欢迎的:

仅仅因为 GET 请求中有太多数据无法容纳而切换到 POST 请求毫无意义 https://stackoverflow.com/a/812935/7489702

另一个:

虽然切换到 POST 会丢弃一些非常有用的功能。 POST 被定义为一种非安全、非幂等的方法。这意味着,如果 POST 请求失败,中间人(例如代理)不能只是假设他们可以再次发出相同的请求。 https://evertpot.com/dropbox-post-api/

另一个:HTTP GET with request body

但与此相反,Elasticsearch 使用 POST 方法来解决查询太长而无法放入 url 的问题。

HTTP GET 和 HTTP POST 都可以用来执行带有正文的搜索。由于并非所有客户端都支持带正文的 GET,因此也允许使用 POST。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html

那么,Elasticsearch 不是真的很安静吗?或者,POST 和 GET 之间的区别在现代浏览器中是否不那么重要?

【问题讨论】:

  • 有些人会称之为实用主义。 POST 在发送搜索正文时有意义,因为两次运行的结果可能不同(即不是幂等的)。
  • 这与“休息”无关——它只是实用的,因为带有 body 的 GET 具有未定义的语义,可能无法在任何地方工作(参见 greenbytes.de/tech/webdav/rfc7231.html#rfc.section.4.3.1.p.4

标签: rest http elasticsearch restful-architecture


【解决方案1】:

那么,Elasticsearch 不是真的很安静吗?或者,POST 和 GET 之间的区别在现代浏览器中是否不那么重要?

我认为 ES 并不是真正的 restful,因为它的查询比普通的 Web 应用程序更复杂。

REST 支持者倾向于使用 URL,例如

http://myserver.com/catalog/item/1729

但 REST 架构不需要这些“漂亮的 URL”。带参数的 GET 请求

http://myserver.com/catalog?item=1729(Elasticsearch 这样做)

在现代开发者中,POST 和 GET 是不同的。

GET 请求应该是幂等的。也就是说,发出两次请求应该与发出一次没有什么不同。这就是使请求可缓存的原因。 “添加到购物车”请求不是幂等的——发出两次会将商品的两个副本添加到购物车中。在这种情况下,POST 请求显然是合适的。因此,即使是 RESTful Web 应用程序也需要它的 POST 请求份额。

参考What exactly is RESTful programming?

【讨论】:

    【解决方案2】:

    ElasticSearch 的意图不是 RESTful,而是向客户端提供(实用的)Web-API,以便索引文档并提供全文搜索或聚合等服务,以帮助客户端满足其需求。

    并非所有通过 HTTP 公开的内容都是自动 RESTful 的。我声称大多数所谓的 RESTful 服务并不像他们认为的那样 RESTful。为了成为 RESTful 服务,必须遵守 couple of constraints,REST 的发明者 Fielding 在 a blog post 中进一步明确了这一点。

    基本上 RESTful 服务应遵守且不违反底层协议,并重点关注资源及其通过媒体类型的呈现。虽然 REST 大部分时间都是通过 HTTP 使用的,但它并不限于此协议。

    另一方面,客户端不应该对 API 中的可用资源或其返回状态 ("typed" resource) 有初步的了解或假设,而是通过发出的请求和分析的响应即时了解它们。这使服务器有机会在不破坏客户端实现的情况下轻松移动或重命名资源。

    HATEOAS(超文本作为应用程序状态的引擎)通过链接丰富资源状态,客户端可以使用链接来触发进一步的请求,以更新其知识库或执行一些状态更改。在这里,客户端应该通过给定的关系名称来确定 URI 的语义,而不是解析 URI,因为如果服务器出于任何原因在资源周围移动,关系名称不应改变。

    客户端还应使用关系名称来确定资源可能具有的内容类型。像news 这样的关系名称可能会强制客户端以application/atom+xml 表示请求资源,而contact 关系可能会导致媒体类型text/vcardvcard+jsonvcard+xml 的表示请求。

    如果您查看我从 dzone 获取的 ElasticSearch 示例,您会发现 ES 根本不支持 HATEOAS:

    请求

    GET /bookdb_index/book/_search?q=guide
    

    回复:

    "hits": [
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "1",
        "_score": 0.28168046,
        "_source": {
          "title": "Elasticsearch: The Definitive Guide",
          "authors": [
            "clinton gormley",
            "zachary tong"
          ],
          "summary": "A distibuted real-time search and analytics engine",
          "publish_date": "2015-02-07",
          "num_reviews": 20,
          "publisher": "manning"
        }
      },
      {
        "_index": "bookdb_index",
        "_type": "book",
        "_id": "4",
        "_score": 0.24144039,
        "_source": {
          "title": "Solr in Action",
          "authors": [
            "trey grainger",
            "timothy potter"
          ],
          "summary": "Comprehensive guide to implementing a scalable search engine using Apache Solr",
          "publish_date": "2014-04-05",
          "num_reviews": 23,
          "publisher": "manning"
        }
      }
    ]
    

    这里的问题是,响应包含与 ElasticSearch 相关的内容,这些内容显然是返回结果的一些任意元数据。虽然这可以通过特殊的媒体类型来处理,这些媒体类型告诉客户端每个字段的语义是什么,保存在_source 元素中的实际有效负载仍然是通用的。在这里,您需要为每种可能的类型进一步自定义媒体类型扩展。

    如果 ES 更改未来客户端的响应格式,假设 _type 将确定资源的类型,_source 将定义该类型的某些对象的当前状态可能会中断并因此停止工作。相反,客户端应该要求服务器以它理解的格式返回资源。如果客户不知道任何请求的表示格式,它将相应地通知客户。如果它至少知道一个,它会将请求资源的状态转换为客户端可以理解的表示。

    长话短说,ElasticSearch 绝不是 RESTful,它也没有尝试成为。相反,您的“RESTful”服务应该使用它并使用结果根据客户端请求的表示生成响应。

    【讨论】:

    • 问题是 Elasticsearch 在技术上确实声称是 RESTful ==> Elasticsearch is a distributed, **RESTful** search and analytics engine capable of solving a growing number of use cases. [link] elastic.co/products/elasticsearch 听起来 RESTful 一词只是在许多不同的变体中使用。
    • @DwayneLove 很好,很多 API 都称自己为 RESTful,但如果您检查 REST 遵守的所有约束,它们并非如此。不幸的是,REST 变成了某种营销术语,因为订购/创建 API 的人要么没有阅读菲尔丁的论文,要么没有理解核心概念。 REST 有其局限性和障碍,而这些局限性和障碍往往被忽视,以促进实用性
    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 2011-08-15
    • 1970-01-01
    • 2013-06-11
    • 2014-08-02
    • 2013-09-16
    • 2012-03-05
    • 1970-01-01
    相关资源
    最近更新 更多