0

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.

Seagull
  • 2,219
  • 6
  • 25
  • 33

2 Answers2

0

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.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • Thankyou @Evert . I made the update to include a "self" link. I am assuming that's what you were pointing to about being incorrect. Unfortunately, the "double" request bug still persists :-( – Seagull Apr 12 '22 at 00:37
0

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.

yejianfengblue
  • 2,089
  • 1
  • 14
  • 18