Best Practice: Requesting resource associations (Etsy.com style?)

150 views
Skip to first unread message

jshock

unread,
May 11, 2012, 10:46:52 PM5/11/12
to api-...@googlegroups.com
I posted about this in the past and am looking for some additional feedback. Etsy uses a convention for requesting associated (nested) resources that consists of the parameter "includes" http://de.etsy.com/developers/documentation/getting_started/resources#section_associations

Examples would be
/dogs?includes=toys,owners

You can also nest up to 3 levels
/dogs?includes=toys/manufacturer,owners

You can filter and only return requested fields
/dogs?includes=toys(name, price),owners(first-name)

Does anyone have any better ideas for doing this? 

The apigee group is great about identifying and rallying around best practices, would they point to Etsy's way as the best way to do this?

Daniel Roop

unread,
May 12, 2012, 11:24:42 AM5/12/12
to api-...@googlegroups.com
I have seen a few of us on this group mention this practice.  I usually refer to it as "expands"  and use a syntax similar to what etsy is describing.  Other places in the wild that I have seen implement this include


And it is also described in REST Design Rule Book 

At my office we have defined a generic syntax (which is basically the same as google's partial response syntax https://developers.google.com/youtube/2.0/developers_guide_protocol_partial.  The major difference we have from the above guys is we basically allow "expansion" on any GET based link relationship.  The risk this opens up to us is that you can have an infinite level of expansion, and we haven't figured out what the right level to allow here is yet.  The above mentioned examples manage this by only allowing a single level, or defining explicit "associations" that can be followed separate from the "links" defined in the URL.  This of course assumes you have a standized way of doing links, and ours is very similar to what Mike Kelly has described in his hal+json format, expect we don't do the "_links" array we just do "links".

In general we only recommend this practice for clients that are far away from the origin server.  Because by performing expansion you reduce the cache-ability of the document.  While you do still get to cache in the network layer the expansion is occurring, it limits how far out in the edge each individual component can live and be shared.  The more things you combine the shorter TTL you are most likely going to get, and you kind of lose all ability to leverage ETags because you are making a dynamic resource, that doesn't really have a PUT equivalent.

The nice thing about this however, is by combining expansion with partial response, you can have clients "design" their own resources when they are in constrained environments without haven't to code individual endpoints for each client.

Mike Kelly

unread,
May 12, 2012, 2:03:34 PM5/12/12
to api-...@googlegroups.com

On 12 May 2012, at 04:24 PM, Daniel Roop <dan...@danielroop.com> wrote:

I have seen a few of us on this group mention this practice.  I usually refer to it as "expands"  and use a syntax similar to what etsy is describing.  Other places in the wild that I have seen implement this include


And it is also described in REST Design Rule Book 

At my office we have defined a generic syntax (which is basically the same as google's partial response syntax https://developers.google.com/youtube/2.0/developers_guide_protocol_partial.  The major difference we have from the above guys is we basically allow "expansion" on any GET based link relationship.  The risk this opens up to us is that you can have an infinite level of expansion, and we haven't figured out what the right level to allow here is yet.  The above mentioned examples manage this by only allowing a single level, or defining explicit "associations" that can be followed separate from the "links" defined in the URL.  This of course assumes you have a standized way of doing links, and ours is very similar to what Mike Kelly has described in his hal+json format, expect we don't do the "_links" array we just do "links".

Cool.. But, fwiw, hal+json uses a json object/hash rather than an array, where links are keyed by their rel

Do you use this pattern or your clients have to iterate through an array?

Cheers,
Mike

Daniel Roop

unread,
May 12, 2012, 2:46:05 PM5/12/12
to api-...@googlegroups.com

We also use a hash style structure.  For the most part this seems preferable. The only down side is you can't have more than one type of "rel" per object. So far that has not proven a huge problem.

Joe Gilvary

unread,
May 15, 2012, 4:00:36 PM5/15/12
to API Craft


On May 12, 2:46 pm, Daniel Roop <goofyp...@gmail.com> wrote:
> We also use a hash style structure.  For the most part this seems
> preferable. The only down side is you can't have more than one type of
> "rel" per object. So far that has not proven a huge problem.

Why can't there be another attribute to differentiate the rels? If an
API served a count of foobaz_foobars sold somewhere, couldn't the
response include this:

"_links": {
"self": { "href": "http://api.example.com/us_of_a/foobars/
foobaz_foobars" },
"parents": [
{ "href": "http://api.example.com/north_america/foobars/
foobaz_foobars", "axis": "geo" },
{ "href": "http://api.example.com/us_of_a/foobars/all", "axis":
"style" }
]
}

In HAL, would this be a use case for "name" attribute? Is the HAL spec
lenient enough that including this snippet (with "axis:") would be
conformant?

Thanks,

Joe

> On May 12, 2012 2:04 PM, "Mike Kelly" <mikekelly...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > On 12 May 2012, at 04:24 PM, Daniel Roop <dan...@danielroop.com> wrote:
>
> > I have seen a few of us on this group mention this practice.  I usually
> > refer to it as "expands"  and use a syntax similar to what etsy is
> > describing.  Other places in the wild that I have seen implement this
> > include
>
> > netflix:
> >http://developer.netflix.com/docs/REST_API_Conventions#0_pgfId-1009162
> > attlassian:
> >https://developer.atlassian.com/display/REST/Atlassian+REST+API+Desig...
>
> > And it is also described in REST Design Rule Book <https://www.amazon.com/dp/1449310508/ref=as_li_ss_til?tag=danroo-20&c...>
>
> > At my office we have defined a generic syntax (which is basically the same
> > as google's partial response syntax
> >https://developers.google.com/youtube/2.0/developers_guide_protocol_p....

Mike Kelly

unread,
May 16, 2012, 3:49:35 AM5/16/12
to api-...@googlegroups.com


On 15 May 2012, at 09:00 PM, Joe Gilvary <feral...@gmail.com> wrote:

>
>
> On May 12, 2:46 pm, Daniel Roop <goofyp...@gmail.com> wrote:
>> We also use a hash style structure. For the most part this seems
>> preferable. The only down side is you can't have more than one type of
>> "rel" per object. So far that has not proven a huge problem.
>
> Why can't there be another attribute to differentiate the rels? If an
> API served a count of foobaz_foobars sold somewhere, couldn't the
> response include this:
>
> "_links": {
> "self": { "href": "http://api.example.com/us_of_a/foobars/
> foobaz_foobars" },
> "parents": [
> { "href": "http://api.example.com/north_america/foobars/
> foobaz_foobars", "axis": "geo" },
> { "href": "http://api.example.com/us_of_a/foobars/all", "axis":
> "style" }
> ]
> }
>
> In HAL, would this be a use case for "name" attribute?

Yeah exactly, that's what name is for - as a 'secondary key' after the rel

Cheers,
Mike
Reply all
Reply to author
Forward
0 new messages