0

Recently while working with feign client in a spring boot application (which in my case is not a web app) I see that the client is not able to de-serialize the object correctly . As pointed to me by by a colleague - it turned out to be due to the HAL module registration is conditional guarded by @ConditionalOnWebApplication on spring auto configuration of hateos

On knowing this there is solutions that could be put in place which would overcome this

  1. We can add a decoder to the feign client which contains the ObjectMapper which has the registered HAL module (small piece of code but still extra work)
  2. Convert to a web application - which i feel is not a good solution at all and should'nt be done in the gist of making things work out of box.

So now knowing this has any one encountered this ? I feel having a feign client for Jpa rest resource is a valid scenario.

Below is an example of the server response which is a Paged. Note the meta-data content in below response received (has one result) but with out the fix when i try to read the content of paged resource it would turns out to be null/empty

        {
        "_embedded": {
            "emails": [{
                "id": "1a5edced-c165-4209-9d1c-9549b6841d13",
                "tenantId": "a56982a6-6e12-4fe6-95d1-b735cedda2dc",
                "email": "whatever@whatever.com",
                "_links": {
                    "self": {
                        "href": "http://10.190.224.138:8086/emails/1a5edced-c165-4209-9d1c-  9549b6841d13"
                    },
                    "email": {
                        "href": "http://10.190.224.138:8086/emails/1a5edced-c165-4209-9d1c-9549b6841d13"
                    }
                }
            }]
        },
        "_links": {
            "self": {
                "href": "http://10.190.224.138:8086/emails/search/whatssss?email=whatever%40whatever.com"
            }
        },
        "page": {
            "size": 20,
            "totalElements": 1,
            "totalPages": 1,
            "number": 0
        }
    }
naav
  • 121
  • 8

2 Answers2

2

Spring Boot autoconfigures hypermedia support under the premise you are attempting to serve hypermedia, not purely consume it.

If you see the need for autoconfiguring various clients, I'd suggest opening an issue against Spring Boot with details about how and why so the Boot team can respond properly.

In light of all that, consuming hypermedia is as easy as:

Traverson client = new Traverson(/* baseUri */, MediaTypes.HAL_JSON); // set up for HAL

...or...

@Configuration
@EnableHypermediaSupport({HypermediaType.HAL})
class ConfigureHypermediaInMyClient {
    @Bean 
    RestOperations restOperations() {
        return new RestTemplate();
    }
}

The first scenario would create an instance of Traverson, used to hop rel-to-rel, and consume HAL. That latter will register an instance of RestTemplate in the application context and then decorate that instance with support for HAL.

IMPORTANT: Anytime you use @EnableHypermediaSupport, Spring Boot will discard its own autoconfiguration details for respect of yours. Building a client only? Fine, because the autoconfiguration is centered on server-side. Building your own server? Then be prepared to take on full configuration.

What about Feign? Neither Spring Boot nor Spring HATEOAS have direct support for Feign at this point in time. To have Feign consume HAL, etc. requires custom setup. Given Feign is aimed at making RPC calls and is URI-centric, hopping across links may not its best usage. Take a look at the Traverson stuff and see if that is more what you seek.

P.S. In light of https://spring.io/blog/2018/01/12/building-richer-hypermedia-with-spring-hateoas, you can also opt in for HAL-FORMS support as well.

gregturn
  • 2,625
  • 3
  • 25
  • 40
  • Thanks for the insights into traverson ..was not aware of this. – naav Feb 26 '18 at 21:05
  • That said I agree this would resolve issues if we have a straight forward URI may be a zuul proxied service in an edge system. In the small internal application i was trying to build earlier - I was trying to consume a service registered with eureka and hence the usage of Feign / ribbon. – naav Feb 26 '18 at 21:16
0

The first one answer proposed by your own, make sense for me, just add the required dependencies inside your project and try again, it should works. On the other, the second seems really a bad idea, you should never think in change you app entirely only to support any library

Rene Enriquez
  • 1,418
  • 1
  • 13
  • 33
  • thanks for the response , the first solution does work . But wanted to know isn't feign client suppose to work for hal+json response irrespective of being called from web environment / non-web environment any thoughts on this ? – naav Jul 18 '16 at 18:39
  • From my perspective, I agree with you, Feign is intended for build rest-clients with no restriction related to web or non-web apps – Rene Enriquez Jul 19 '16 at 22:23