Skip to content

Hinting of embedded resources #16

@weierophinney

Description

@weierophinney

I've been struggling with a problem for some time regarding how relationship are handled on entities, specifically when embedded into a resource. The problem (and I assume it is a fairly common one) is how to provide relationships in a sane and dependable way without returning the entire (or most of the) database in embedded resources (and dealing with looping recursion problems) or always needing to fetch relationships. HAL spec is a bit fuzzy on how _embedded resources are supplied which makes it harder to create a dependable abstract consumers. For example, HAL Clients don't know if the non-rendered entity is actually rendered or not (or is just a link) or whether it is a full or partial rendering. The first case is an easier problem to solve abstractly and a few suggestions are below.

For the sake of example lets assume the following:

  • We have a table of people and each person has a relationship for their best friend and their gender.
    ** person --> one-to-many (bestFriend) --> person
  • We have render_embedded_entities set to false

We can either:

  1. Depend on clients to inspect the payload and if the only property is the _links object, the client should understand to fetch that resource also when needed. This is how it is currently working
{
    "id": "123",
    "name": "Jane Doe",
   "gender": "female",
    "_embedded": {
        "bestFriend": {
            "_links": {
                "self": {
                    "href": "http://abc.tld/api/person/456"
                }
            }
        }
    },
    "_links": {
        "self": {
            "href": "http://abc.tld/api/person/123"
        }
    }
}
  1. Providing a 'profile' parameter which can be used as a hint
    Link Only:
{
    "id": "123",
    "name": "Jane Doe",
    "gender": "female",
    "_embedded": {
        "bestFriend": {
            "_profile": "link",
            "_links": {
                "self": {
                    "href": "http://abc.tld/api/person/456"
                }
            }
        }
    },
    "_links": {
        "self": {
            "href": "http://abc.tld/api/person/123"
        }
    }
}

Partial Resource:

{
    "id": "123",
    "name": "Jane Doe",
    "gender": "female",
    "_embedded": {
        "bestFriend": {
            "name": "John Smith",
            "_profile": "partial",
            "_links": {
                "self": {
                    "href": "http://abc.tld/api/person/456"
                }
            }
        }
    },
    "_links": {
        "self": {
            "href": "http://abc.tld/api/person/123"
        }
    }
}
  1. Provide the embedded entities as _links on the resource instead of embedding the entity that contains only the link (removes any ambiguity).
{
    "id": "123",
    "name": "Jane Doe",
    "gender": "female",
    "_links": {
        "self": {
            "href": "http://abc.tld/api/person/123"
        },
        "bestFriend": {
            "href": "http: //abc.tld/api/person/456"
        }
    }
}

I've created PR #118 to show an example of how we can enabling linking insteading of embedding and would love to get feedback on how others are solving this kind of issue, and/or if I should focus time on building out one of the above potential solutions.


Originally posted by @nobesnickr at zfcampus/zf-hal#118

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions