25

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?

Ben M
  • 1,833
  • 1
  • 15
  • 24
  • Yes, you would do it with a different Accept header. – Jonathan W Nov 22 '14 at 20:53
  • 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. – Ben M Nov 23 '14 at 21:48
  • 1
    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. – Jonathan W Nov 24 '14 at 17:30

1 Answers1

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

Community
  • 1
  • 1
gyoder
  • 4,530
  • 5
  • 29
  • 37
  • 25
    i'm surprised you cannot override the serializer/message converter to just not output the links...seems like it should be possible – Chris DaMour Nov 25 '14 at 18:40
  • 9
    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. – Ben M May 27 '21 at 15:01
  • 5
    7 years later, I agree with you. :) – gyoder May 28 '21 at 17:58