Question

I use the self href from my HAL resources on the client side to find the right path for the CRUD operations. In single(ton) resources this is working fine (see the address resource below, the _links containing the self href is included in the embedded resource) but when it comes down to collections this is a different story. The _links of a collection are not rendered when the collection is in _embedded.

Earlier I worked around this problem by reading the url form the first child. But this is not sufficient. In case the collection is empty I only have an empty array with no possibility to extract the url like that. If I want to create a new item in the collection I would like that my client knows where to send data using POST by reading the self href from _links. Is it a good idea to include the _links to my collection like this:

{
    "_links": {
        "self": {
            "href": "http://example.com/api/v1/users/1"
        }
    },
    "_embedded": {
        "contacts": {

Now I have access to the self href here:

            "_links": {
                "self": {
                    "href": "http://example.com/api/v1/users/1/contacts"
                }
            },
            "_embedded": {
                "contacts": [
                    {
                        "_links": {
                            "self": {
                                "href": "http://example.com/api/v1/users/1/contacts/2"
                            }
                        },
                        "id": "2",
                        "name": "John Smith"
                    },
                    {
                        "_links": {
                            "self": {
                                "href": "http://example.org/api/v1/users/1/contacts/3"
                            }
                        },
                        "id": "3",
                        "name": "Jane Doe"
                    }
                ],
            }
        },
        "address": {
            "_links": {
                "self": {
                    "href": "http://example.com/api/v1/addresses/1"
                }
            },
            "street": "Bakerstreet 11",
            "postal code": "123456",
            "city": "Some city",
            "country": "Some country",
        }
    },
    "id": "1",
    "name": "John Doe"
}

EDIT (one year later)

In the end I solved this by always adding the links of embedded resources to the parent resource. So in the example above my response object would look like this:

{
    "_links": {
        "self": {
            "href": "http://example.com/api/v1/users/1"
        },
        "contacts": {
            "href": "http://example.com/api/v1/users/1/contacts"
        },
        "address": {
            "href": "http://example.com/api/v1/addresses/1"
        }
    },
    "_embedded": {
        "contacts": [
            {
                "_links": {
                    "self": {
                        "href": "http://example.com/api/v1/users/1/contacts/2"
                    }
                },
                "id": "2",
                "name": "John Smith"
            },
            {
                "_links": {
                    "self": {
                        "href": "http://example.org/api/v1/users/1/contacts/3"
                    }
                },
                "id": "3",
                "name": "Jane Doe"
            },
        ],
        "address": {
            "_links": {
                "self": {
                    "href": "http://example.org/api/v1/addresses/1"
                }
            },
            "street": "Bakerstreet 11",
            "postal code": "123456",
            "city": "Some city",
            "country": "Some country",
        }
    },
    "id": "1",
    "name": "John Doe"
}

So no matter whether I embedded the resources or not I always know where they are located. And for the contacts collection I will have the link to my collection endpoint in the _links array and the contacts themselves in _embedded.

Was it helpful?

Solution

Yes. It's not only good practice to do so; it's recommended by the HAL spec:

Each Resource Object SHOULD contain a 'self' link that corresponds with the IANA registered 'self' relation (as defined by RFC5988) whose target is the resource's URI.

A collection of resources is itself a resource, don't forget.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top