0

I am designing an API that will need to accept a large amount of data in order to return resources. I thought about using a POST request instead of a GET so I can pass a body with the request. That has been largely frowned upon in the REST community:

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

Another:

Switching to POST discards a number of very useful features though. POST is defined as a non-safe, non-idempotent method. This means that if a POST request fails, an intermediate (such as a proxy) cannot just assume they can make the same request again. https://evertpot.com/dropbox-post-api/

Another: HTTP GET with request body

But contrary to this, Elasticsearch uses POST methods to get around the issue of queries being too long to put in a url.

Both HTTP GET and HTTP POST can be used to execute search with body. Since not all clients support GET with body, POST is allowed as well.https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html

So, is Elasticsearch not truly restful? Or, does the difference between POST and GET not matter as much in modern browsers?

Dwayne Love
  • 303
  • 3
  • 10
  • Some would call it pragmatism. POST makes sense when sending a search body, because the results might differ between two runs (i.e. not idempotent). – Val Sep 01 '17 at 15:21
  • 2
    This has nothing to do with being "restful" - it's just pragmatic as GET with body has undefined semantics and might not work everywhere (see https://www.greenbytes.de/tech/webdav/rfc7231.html#rfc.section.4.3.1.p.4) – Julian Reschke Sep 02 '17 at 04:09

2 Answers2

0

So, is Elasticsearch not truly restful? Or, does the difference between POST and GET not matter as much in modern browsers?

I think ES is not truly restful, because it's query is more complex than normal Web Application.

REST proponents tend to favor URLs, such as

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

but the REST architecture does not require these “pretty URLs”. A GET request with a parameter

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

It is difference POST and GET in modern developer.

GET requests should be idempotent. 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. Thus, even a RESTful web application needs its share of POST requests.

reference What exactly is RESTful programming?

beehuang
  • 172
  • 1
  • 14
0

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.

Not everything that is exposed via HTTP is automatically RESTful. I claim that most of the so called RESTful services aren't as RESTful as they think they are. 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.

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. Altough REST is used via HTTP most of the time, it is not restricted to this protocol.

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. 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. 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.

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.

If you look at an ElasticSearch sample I took from dzone you will see that ES does not support HATEOAS at all:

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. 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. 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. 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. Instead your "RESTful" service should use it and use the results to generate a response in accordance with the requested representation by the client.

Roman Vottner
  • 9,720
  • 4
  • 38
  • 48
  • Well the thing is that Elasticsearch does technically claim to be RESTful ==> `Elasticsearch is a distributed, **RESTful** search and analytics engine capable of solving a growing number of use cases.` [link] https://www.elastic.co/products/elasticsearch Sounds like the term RESTful just gets used in many different variations. – Dwayne Love Sep 28 '17 at 17:35
  • @DwayneLove well, plenty of APIs call themselfs RESTful though they aren't if you check all the constraints REST obeys. REST became some kind of marketing-term unfortunately as the ones ordering/creating the API either have not read Fieldings dissertation or have not understood the core concepts. REST has its limitations and hurdles that are often neglected in favor of practicability – Roman Vottner Sep 28 '17 at 18:11