简体   繁体   English

Elasticsearch真正RESTful吗?

[英]Elasticsearch truly RESTful?

I am designing an API that will need to accept a large amount of data in order to return resources. 我正在设计一个API,该API需要接受大量数据才能返回资源。 I thought about using a POST request instead of a GET so I can pass a body with the request. 我考虑过使用POST请求而不是GET,这样我就可以通过请求传递正文。 That has been largely frowned upon in the REST community: 在REST社区中,大多数人对此表示反对:

Switching to a POST request simply because there's too much data to fit in a GET request makes little sense https://stackoverflow.com/a/812935/7489702 仅仅因为GET请求中容纳的数据太多而切换到POST请求没有任何意义https://stackoverflow.com/a/812935/7489702

Another: 另一个:

Switching to POST discards a number of very useful features though. 切换到POST会丢弃许多非常有用的功能。 POST is defined as a non-safe, non-idempotent method. POST被定义为一种非安全,非幂等方法。 This means that if a POST request fails, an intermediate (such as a proxy) cannot just assume they can make the same request again. 这意味着,如果POST请求失败,则中间设备(例如代理)不能仅仅假设它们可以再次发出相同的请求。 https://evertpot.com/dropbox-post-api/ https://evertpot.com/dropbox-post-api/

Another: HTTP GET with request body 另一个: 带有请求正文的HTTP GET

But contrary to this, Elasticsearch uses POST methods to get around the issue of queries being too long to put in a url. 但是与此相反,Elasticsearch使用POST方法来解决查询太长而无法放入url的问题。

Both HTTP GET and HTTP POST can be used to execute search with body. HTTP GET和HTTP POST均可用于使用主体执行搜索。 Since not all clients support GET with body, POST is allowed as well. 由于并非所有客户端都支持带有主体的GET,因此也允许POST。 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html https://www.elastic.co/guide/zh-CN/elasticsearch/reference/current/search-request-body.html

So, is Elasticsearch not truly restful? 那么,Elasticsearch难道不是真正的宁静吗? Or, does the difference between POST and GET not matter as much in modern browsers? 或者,在现代浏览器中POST和GET之间的区别是否没有太大关系?

So, is Elasticsearch not truly restful? 那么,Elasticsearch难道不是真正的宁静吗? Or, does the difference between POST and GET not matter as much in modern browsers? 或者,在现代浏览器中POST和GET之间的区别是否没有太大关系?

I think ES is not truly restful, because it's query is more complex than normal Web Application. 我认为ES并不是真正的烦人,因为它的查询比普通的Web应用程序复杂。

REST proponents tend to favor URLs, such as REST支持者倾向于使用URL,例如

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

but the REST architecture does not require these “pretty URLs”. 但是REST体系结构不需要这些“漂亮的URL”。 A GET request with a parameter 带有参数的GET请求

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

It is difference POST and GET in modern developer. 是现代开发人员中的POST和GET区别。

GET requests should be idempotent. GET请求应该是幂等的。 That is, issuing a request twice should be no different from issuing it once. 也就是说,两次发出请求应该与一次发出请求没有什么不同。 That's what makes the requests cacheable. 这就是使请求可缓存的原因。 An “add to cart” request is not idempotent—issuing it twice adds two copies of the item to the cart. “添加到购物车”请求不是幂等的-发出两次请求会将该商品的两个副本添加到购物车。 A POST request is clearly appropriate in this context. 在这种情况下,POST请求显然是适当的。 Thus, even a RESTful web application needs its share of POST requests. 因此,即使是RESTful Web应用程序也需要其POST请求共享。

reference What exactly is RESTful programming? 参考什么是RESTful编程?

ElasticSearch intent is not to be RESTful but to provide a (pragmatic) Web-API to clients in order to index documents and offer services like fulltext search or aggregations to help the client in its needs. ElasticSearch的目的不是要具有REST功能,而是要为客户端提供(实用)Web-API,以便为文档建立索引并提供全文搜索或聚合之类的服务来帮助客户端满足其需求。

Not everything that is exposed via HTTP is automatically RESTful. 并非所有通过HTTP公开的内容都是自动RESTful的。 I claim that most of the so called RESTful services aren't as RESTful as they think they are. 我声称大多数所谓的RESTful服务并不像他们认为的那样具有RESTful功能。 In order to be RESTful a service has to adhere to a couple of constraints which Fielding, the inventor of REST, precisied further in a blog post . 为了成为RESTful,服务必须遵守几个约束 ,REST的发明者Fielding在博客中进一步规定了这些约束

Basically RESTful services should adhere to and not violate the underlying protocol and put a strong focus on resources and their presentation via media-types. 基本上,RESTful服务应该遵守并且不违反底层协议,并且将重点放在通过媒体类型的资源及其表示上。 Altough REST is used via HTTP most of the time, it is not restricted to this protocol. REST大部分时间都是通过HTTP使用的,但不限于此协议。

Clients on the other hand should not have initial knowledge or assumptions on the available resources or their returned state ( "typed" resource ) in an API but learn them on the fly via issued requests and analyzed responses. 另一方面,客户端不应该对API中的可用资源或其返回状态( “类型化”资源 )有初步的了解或假设,而应通过发出的请求和已分析的响应即时了解它们。 This gives the server the opportunity to move arround or rename resources easily without breaking a client implementation. 这为服务器提供了轻松移动周围环境或重命名资源的机会,而不会破坏客户端的实现。

HATEOAS (Hypertext as the engion of aplication state) enriches a resource state with links a client can use to trigger further requests in order to update its knowlege base or perform some state changes. HATEOAS(超文本作为应用程序状态的实体)通过客户端可用来触发更多请求的链接来丰富资源状态,以更新其知识库或执行某些状态更改。 Here a client should determine the semantics of an URI by the given relation name rather than parse the URI as the relation name should not change if the server moves arround a resource for whatever reason. 在这里,客户端应通过给定的关系名称确定URI的语义,而不是解析URI,因为如果服务器出于任何原因移动资源周围时,关系名称都不应更改。

The client furthermore should use the relation name to determine what content type a resource may have. 客户端还应该使用关系名称来确定资源可能具有的内容类型。 A relation name like news could force the client to request the resource as application/atom+xml representation while a contact relation might lead to a representation request of media-type text/vcard , vcard+json or vcard+xml . 诸如news类的关系名称可能会迫使客户端以application/atom+xml表示形式请求资源,而contact关系可能导致媒体类型text/vcardvcard+jsonvcard+xml的表示形式请求。

If you look at an ElasticSearch sample I took from dzone you will see that ES does not support HATEOAS at all: 如果您查看我从dzone取得的ElasticSearch示例,您会发现ES根本不支持HATEOAS:

Request 请求

GET /bookdb_index/book/_search?q=guide

Response: 响应:

"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"
    }
  }
]

The problem here is, that the response contains ElasticSearch related stuff that obviously is some arbitrary metadata for the returned results. 这里的问题是,响应包含与ElasticSearch相关的东西,显然是返回结果的一些任意元数据。 While this could be handled via special media-types that teaches a client what each fields semantics are the actual payload kept in the _source element is still generic. 尽管这可以通过特殊的媒体类型来处理,该媒体类型告诉客户端每个字段的语义是什么,但_source元素中保留的实际有效载荷仍然是通用的。 Here you'd need further custom media-type extensions for each possible type. 在这里,您需要针对每种可能的类型进一步定制媒体类型扩展。

If ES changes the response format in future clients which assume that _type will determine the type of a resource and _source will define the current state of some object of that type may break and hence stop working. 如果ES在将来的客户端中更改响应格式,则假定_type将确定资源的类型,而_source将定义该类型的某些对象的当前状态,则该状态可能会中断并因此停止工作。 Instead a client should ask the server to return a resource in a format it understands. 相反,客户端应要求服务器以其理解的格式返回资源。 If the client does not know any of the requested representation formats it will notify the client accordingly. 如果客户端不知道任何请求的表示形式,它将相应地通知客户端。 If it knows at least one it will transform the state of the requested resource to a representation the client understands. 如果知道至少一个,它将把请求资源的状态转换为客户端可以理解的表示形式。

Long story short, ElasticSearch is by no means RESTful and it also does not try to be. 长话短说,ElasticSearch绝不是RESTful的,它也不是。 Instead your "RESTful" service should use it and use the results to generate a response in accordance with the requested representation by the client. 相反,您的“ RESTful”服务应使用它,并使用结果根据客户端请求的表示来生成响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM