Optionally disable HATEOAS format in Spring Data Rest
The short answer is, you can't use spring-data-rest without hateoas. If you want to build your web service without hateoas, you'll have to write your own controllers (which can still use spring-data repositories).
Quoting Oliver Gierke in this SO post:
Actually my whole point is: the server is just doing decent REST. If that breaks the client, it's the client that needs to be fixed (tweaked). So the hypermedia aspect is a fundamental one to Spring Data REST and we're not going to back out of that. That's probably not satisfying in your concrete situation but should answer the question at least :). – Oliver Gierke
Related videos on Youtube
Ben M
I like to build things. Especially in the cloud, using the jvm.
Updated on October 26, 2021Comments
-
Ben M over 2 years
So let's say I have an existing application that has two endpoints /people and /pants. Calling GET /people returns:
[ { "name":"john", "age":37, "pants":[ { "color":"green", "brand":"levis", "size":"medium" }, { "color":"indigo", "brand":"jncos", "size":"medium-with-huge-legs" } ] }, { "name":"june", "age":23, "pants":[ { "color":"pink", "brand":"gap", "size":"small" } ] } ]
If i were to use Spring Data Rest and call GET /person i'd receive something like:
{ "_links":{ "next":{ "href":"http://myapp.com/people?page=1&size=20" }, "self":{ "href":"http://myapp.com/people{&page,size,sort}", "templated":true }, "search":{ "href":"http://myapp.com/people/search" } }, "_embedded":{ "people":[ { "name":"john", "age":37, "_links":{ "self":{ "href":"http://myapp.com/people/john" }, "pants":{ "href":"http://myapp.com/people/john/pants" } } }, { "name":"june", "age":23, "_links":{ "self":{ "href":"http://myapp.com/people/june" }, "pants":{ "href":"http://myapp.com/people/june/pants" } } } ] } }
Let's say I have a bunch of existing clients that I don't want to have to change - is there any way to disable the hypermedia portions of the response in some cases (say Accept="application/json") but enable it them for others (Accept="hal+json")?
Thanks!
Updated
Okay - so it appears that much to my chagrin, what I'm looking to do is not supported. I understand why Spring Data Rest is strongly leaning toward Hypermedia... but I don't buy that providing the capability to "disable" hypermedia based on a header thus providing more options is a bad thing.
That aside, I'm a bit unsure of how to actually achieve this via my own Controllers. If I create a Controller and attempt to override the
/people
RequestMapping withproduces = "application/json" I am able to get the "raw" json back with Accept="application/json" but if I pass
Accept="application/hal+json"` I get a 406 with "Could not find acceptable representation". It looks like the SDR resource mappings aren't mapped with a content type ... any suggestions?-
Jonathan W over 9 yearsYes, you would do it with a different Accept header.
-
Ben M over 9 yearsJonathan, the question isn't really around how to know when to return the non-hateoas response but instead how would I enable Spring Data Rest to not generate the Hypermedia elements in the response.
-
Jonathan W over 9 yearsI believe that Spring Data REST uses two different HttpMessageConverters for this, and that they are in a chain. If the Accept header indicates application/hal+json, the TypeConstrainedMappingJackson2HttpMessageConverter will handle it and produce HAL. If, however, the header is only 'application/json', the regular MappingJackson2HttpMessageConverter kicks in and will not serialize to HAL. Not sure if that helps, but I would look at trying to tweak this latter converter to not return hypermedia links.
-
-
Chris DaMour over 9 yearsi'm surprised you cannot override the serializer/message converter to just not output the links...seems like it should be possible
-
Ben M almost 3 yearsI accepted this answer, but 7 years later, i still fundamentally disagree with Drotbohm's insistence on HATEOAS. I think time has continued to show us that in practical terms, very very very few consumers are actually interested or able to make use of the affordances.
-
gyoder almost 3 years7 years later, I agree with you. :)