Optionally disable HATEOAS format in Spring Data Rest
Asked Answered
D

1

26

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 with produces = "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?

Dustproof answered 21/11, 2014 at 21:47 Comment(3)
Yes, you would do it with a different Accept header.Geraldine
Jonathan, 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.Dustproof
I 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.Geraldine
K
21

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

Kanaka answered 23/11, 2014 at 22:6 Comment(3)
i'm surprised you cannot override the serializer/message converter to just not output the links...seems like it should be possibleSulfite
I 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.Dustproof
7 years later, I agree with you. :)Kanaka

© 2022 - 2024 — McMap. All rights reserved.