'Should using Traverson for consuming Spring HATEOAS HAL response result in duplicate invocations of the service?
I have a REST endpoint (like http://myapi.rest.com/someEndpoint?offset=40&limit=20) that vends out HAL JSON response like the following
{
"_embedded": {
"listOfObjects": [
{
"att1":"value1",
"att2":"value2"
}
]
},
"_links": {
"self": {
"href": "http://myapi.rest.com/someEndpoint?offset=40&limit=20"
},
"next": {
"href": "http://myapi.rest.com/someEndpoint?offset=60&limit=20"
},
"prev": {
"href": "http://myapi.rest.com/someEndpoint?offset=20&limit=20"
},
"last": {
"href": "http://myapi.rest.com/someEndpoint?offset=14640&limit=20"
},
"first": {
"href": "http://myapi.rest.com/someEndpoint?offset=0&limit=20"
}
},
"page": {
"size": 20,
"totalElements": 14659,
"totalPages": 733,
"number": 2
}
}
The Traverson code that I use to consume this is
public PagedResources<Resource<SomePojoVO>> getSomePojo(){
Traverson traverson = new Traverson(URI.create(url), MediaTypes.HAL_JSON);
ParameterizedTypeReference<PagedResources<Resource<SomePojoVO>>> pojoVOs =
new ParameterizedTypeReference<PagedResources<Resource<SomePojoVO>>>() {};
return traverson.follow("$._links.self.href").toObject(pojoVOs);
}
When looking at the access logs for myapi.rest.com. I notice that two invocations are made. One is when the Traverson object is created and the other when follow() is invoked. I've also tried to do the following
traverson.follow("$._embedded").toObject(pojoVOs);
but I get an UriSyntaxException with the message Illegal character in scheme name at index 0: { thrown at TraversonBuilder.traverseToExpandedFinalUrl where it tries to invoke the code new UriTemplate(uri) with uri resulting in the value of _embedded.
I feel like I am doing something wrong here, as having to invoke the endpoint twice to try to get PagedResources<Resource<SomePojoVO>> seems incorrect.
Does anyone have any pointers about what I might be doing wrong here?
Some other information. I am using Spring HATEOAS v 0.25.2, and I am not able to upgrade at this point.
Thank you for your responses/help.
Solution 1:[1]
Your format for _embedded is wrong.
Each item in the listOfObjects array should itself by a HAL resource. If you can't fix the output, then your server is broken to a point that a valid HAL parser won't be able to read it. Your only choice might then be to write your own client, or modify Traverson to support your variation of the format.
I don't have a solution for the double-request bug, although I do work on a different client for javascript that doesn't have that bug. However, that client also won't be able to parse your JSON format without modification.
Solution 2:[2]
The double request is not a bug. The first request to http://myapi.rest.com/someEndpoint?offset=40&limit=20 fetches the json response body you posted. Then traverson finds a link path and make the second get request if that path exists.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Evert |
| Solution 2 | yejianfengblue |
