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.