Search code examples
hateoasspring-hateoashal-json

What's the correct way to present paged resources with HAL?


This sounds like a rookie question, but I'm wondering what's the best way to present paged resources with HAL format? Right now I'm using Spring HATEOAS API to convert Page object into resource PagedResourcesAssembler#toResource(Page<T>, ResourceAssembler<T,R>). This results in the following output:

{
"_links": {
    "self": {
        "href": "http://example.org/api/user?page=3"
    },
    …
}
"count": 3,
"total": 498,
"_embedded": {
    "users": [
        {
            "_links": {
                "self": {
                    "href": "http://example.org/api/user/mwop"
                }
            },
            "id": "mwop",
            "name": "Matthew Weier O'Phinney"
        }
    ]
}

}

Everything works fine but the only problem is the collection being returned is under _embedded field and has the class name, so the client has to know this class name as well right? Would it be better to just return the collection under content like non-HAL format? If yes how should I achieve it using Spring HATEOAS?


Solution

  • That's not a problem, that's the way _embedded is defined in the HAL specification.

    users is not a class, it's a link relation that will allow clients to actually find the collection it was asking for in the first place (e.g. using a JSONPath expression). That's not something coming out of the blue at all but usually is the same link relation, the client used to find that resource in the first place.

    Assume an API root exposing this document:

    {
      "_links": {
        "users": {
          "href": "…"
        },
        …
      }
    }
      
    

    Seeing that, the client would have to know the semantics of users to find the link it wants to follow. In your case users is basically pointing to a collection resource that supports pagination.

    So if the client follows the link named users, it can then find the actual content it's looking for under _embedded.users in the HAL response by combining knowledge about the media type (HAL, _embedded) and the service's application-level semantics (users).