Elasticsearch真的是RESTful吗?

时间:2017-09-01 15:12:48

标签: rest http elasticsearch restful-architecture

我正在设计一个API,需要接受大量数据才能返回资源。我想过使用POST请求而不是GET,所以我可以传递一个带有请求的正文。这在REST社区中基本上是不受欢迎的:

  

切换到POST请求只是因为太多数据不适合GET请求是没有意义的   https://stackoverflow.com/a/812935/7489702

另:

  

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

另一个:HTTP GET with request body

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

  

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

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

2 个答案:

答案 0 :(得分:0)

  

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

我认为ES并不是真正的宁静,因为它的查询比普通的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?

答案 1 :(得分:0)

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

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

基本上,RESTful服务应该遵守而不是违反底层协议,并通过媒体类型强调资源及其呈现。在大多数情况下,通过HTTP使用Altough REST,它不限于此协议。

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

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

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

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

请求

vcard+xml

响应:

GET /bookdb_index/book/_search?q=guide

这里的问题是,响应包含ElasticSearch相关的东西,显然是返回结果的一些任意元数据。虽然这可以通过特殊的媒体类型来处理,这些媒体类型教会客户端每个字段语义是什么,"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" } } ] 元素中保存的实际有效负载仍然是通用的。在这里,您需要为每种可能的类型提供进一步的自定义媒体类型扩展。

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

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