REST API - include related object details or just

2020-05-26 11:25发布

问题:

What is the better design practice?

If I have object A and it contains some related objects for example I have a car object and it's various types.

Should I on request api.example.org/cars/1 respond just with ID's to those resources (so if someone need details about them another API call is required at api.example.org/type/1)

{
    "id": 1,
    "name": "Some Car",
    "types": [
        1,
        2
    ]
}

or provide details about those resources as well

{
    "id": 1,
    "name": "Some Car",
    "types": [
        {
            "id": 1,
            "name": "Some Type",
            "something": "Blah"
        },
        {
            "id": 2,
            "name": "Some Type",
            "something": "Blah"
        }
    ]
}

Or provide optional parameter like "displayAll" and then array with names of parameters which should be retrieved all in one API call (in this case types).

回答1:

This touches one of the core principles of REST called HATEOAS (Hypermedia As The Engine Of Application State).

Object IDs are useless and meaningless to clients. What do you do with them? Feed them to a search function? Construct a new URI with them appended to the end of it? Phone a 1-800 number and ask what to do with them? Print them out on paper and mail them to a government agency that helps API clients find their next steps?

Just return the full URI, all the time. The ID given to the client should always be the URI - it's something which uniquely identifies the resource in question and can be used to retrieve, update or remove it.



回答2:

I prefer the parameterless version of option 1, but I would favor something where the location of the type resource is returned, so that the client may choose whether or not to retrieve those resources.

Otherwise, we are not navigating the documents. Rather, we would be relying upon some out-of-band data, such as knowing the path to the type in advance.

{
    "id": 1,
    "name": "Some Car",
    "types": [
        {
            "location": "api.example.org/type/1"
        },
        {
            "location": "api.example.org/type/2"
        }
    ]
}