I started this conversation with @geemus via an email. We decided to make our discussion public for feedback.
I've been developing some API Design notes internally for our team at KISSmetrics. I wrote out our base design patterns, research notes, as well as resources for further information.
I had a question for you. In the section Next foreign key relations, you mention utilizing nesting versus owner_id.
In my experience building API clients I have appreciated both approaches:
When a client expands the full relation, I prefer the approach you mentioned.
When a client gives reference to the relation without providing the full body I prefer the owner_id approach.
This way the client doesn't have to inspect the relation envelope to see if it has the full relation or if it needs to look it up via an other request.
I still make the object available in the links envelope. This way a client can manage expansion or firing off another request if necessary. The option is left up to the client for performance.
Good question. I err on the side of consistency where I can, so I'm in favor of always nesting (since it works in both cases). It does provide some possible ambiguity between foreign key and full representations. In our case they are (presently) only ever the foreign key(s), we have a rough plan to allow for users to ask for expanded representations in to the existing envelope in this case (probably via the user passing a header or query string). Since you would need to explicitly ask for the expanded version, I think the ambiguity of foreign keys vs full representation should be somewhat reduced at least. Does that help/make sense? I'm certainly up for having further discussion and would certainly be interested to here more about your guide as it develops.
My (@nateklaiber) response:
I agree with the desire for consistency. I also agree that if you are asking for expanded versions that the ambiguity should be reduced. In practice I have found this a little tough, as many times I wrap the JSON responses in an object model. Here's an example when working with Stripe.
As I mentioned there, there may be better approaches which I am open to.
Yeah, I guess since we expect you would always have to explicitly expand, that it isn't so bad. In our case most of our serializations are fairly streamlined, so most of the overhead is in DB lookup anyway, so just returning the full thing seemed easiest (and helps prevent inadvertent n+1 stuff from naive clients). I guess my inclination would be toward defaulting to this easier to consume/harder to do wrong version and then perhaps allowing you to narrow the returned value as an optimization or something.
That said, I do think expanding a nested thing from foreign key to full serialization is also a good thing to allow opting-in to for optimization purposes.
It definitely depends a lot on specifics though, I'm not totally convinced we are universally correct there or anything, but it is working well for us and I think could work well for others (but we have other assumptions rolled in there I'm guessing).
I've been developing some API Design notes internally for our team at KISSmetrics. I wrote out our base design patterns, research notes, as well as resources for further information.
I had a question for you. In the section Next foreign key relations, you mention utilizing nesting versus
owner_id
.In my experience building API clients I have appreciated both approaches:
owner_id
approach.This way the client doesn't have to inspect the relation envelope to see if it has the full relation or if it needs to look it up via an other request.
I still make the object available in the
links
envelope. This way a client can manage expansion or firing off another request if necessary. The option is left up to the client for performance.Here is an example that may better describe my question.
@geemus responded with:
My (@nateklaiber) response:
I agree with the desire for consistency. I also agree that if you are asking for expanded versions that the ambiguity should be reduced. In practice I have found this a little tough, as many times I wrap the
JSON
responses in an object model. Here's an example when working with Stripe.As I mentioned there, there may be better approaches which I am open to.
I have copied parts of our guide - it's a work in progress.
@geemus then responded with: