I don't know Flux, and my answer is "it depends".
Edit with summary: I would choose between either (A) including attendee resrouces directly under meetings (and not optimizing as you have done), or (B) not include them at all and only provide URIs of the attendee resources. Choice (A) is a reasonable compromise in my eyes.
If you're aiming to be as RESTful as possible, including two top-level resources (meetings
and allUsersIntersectedByMeetings
) don't fit well.
Instead, you could have your /meetings
collection of meetings that's responsible for returning meetings. A network maybe-not-efficient way is to add links from a meeting
resource to the URL of each of its attendees.
It's possible then that your browser will cache attendees (people) that it has already request in the past.
Rather than links, you can include the attendee objects direclty, like:
{
"meetings": [
{
"id": 1,
"attendees": [
{
"id": 1,
"name": "Oscar"
}
]
]
}
By the way, the "JSON API" standard uses an includes
section like your original example. I'm not sure how RESTful or not that approach is.
Let's say I have an Employee resource, which has a status and gender attributes. In the database Status and Gender and separate tables and thus separate Domain object, each with its own identifier.
Your API representations should not be tightly coupled to your implementation details. I'd go so far as to say that deriving your API representations from your implementation details is exactly backwards.
Think Adapter Pattern
from the Gang of Four book. The messages of the web are that of a document store. Your goal in creating an API is to produce the documents that your consumers want, while insulating them from the nitty gritty details of producing those documents.
The motivation for doing so, is that you can then change the implementation details any time you want, secure in the knowledge that -- so long as you don't change the representations you return, your clients won't break.
Also, keep in mind that a single logical resource might have many representations, only some of which support modification.
let's say the client is updating the user
As a consumer, which representation do you want to work with? My guess is that the closest is
{
"firstName": "Jane",
"lastName": "Doe",
"active": true,
"gender": "FEMALE",
"status": "FULL_TIME"
}
If I PUT that representation to a location that you specify, you really ought to be able to work out the rest.
If you were creating representations for machines to use, then you'd probably want less ambiguity in your spelling
{
"https://schema.org/givenName": "Jane",
"https://schema.org/familyName": "Doe",
"active": true,
"https://schema.org/gender": "https://schema.org/Female",
"https://schema.org/employmentType": "FULL_TIME"
}
Same logical resource, two different representations. Horses for courses.
Best Answer
You have stated your choice that pets have a globally unique id. This means that a pet can be transferred to another owner without changing the pet's id (generally a good thing for stability under db refactoring). Further, it means that should you want to, you can have two owners (e.g. a couple or roommates, etc..) for the pet. (Not to mention directly referencing a pet as you note.)
Therefore, I'd say use the
/pets/<id>
.However, you can still list pets for one user with
/users/1/pets
, and user for pet with/pets/<id>/user
(if limited to one or/pets/<id>/users
for more), for one, because we're talking about the API here not your normalized database hidden behind it. The use of simple integers for ID's may be confusing (so you could use something else), but when people see that/pets
is an endpoint, I think they'll get it.Have a look a OData, if you haven't seen it already. A good way to layer on top of REST, and provide for filters, nested data, even doing joins, from an API perspective. For example, https://stackoverflow.com/q/3920758/471129 gives a good discussion about using navigational properties for specific joins without having to introduce foreign keys.
Also, I think you will eventually want to remove the limitation of one owner per pet, as this is not going to stand the test of time. Cars, houses, bank accounts, all have notions of multiple owners. Children can have multiple guardians, why not pets having multiple owners.