Closed gxxcastillo closed 10 years ago
WRT item 1 (invalid URL):
I've been thinking about similar ideas for my api. Here's my thoughts:
http://api.example.com/purchase/1
Returns a purchase order resource which contains an entity link with rel ''customer".
You could return the purchase resource with a full customer entity like such:
http://api.example.com/purchase/1?expand=customer
If the purchase order resource contained multiple entity links with rel of 'orderItem' you could return all orderItems expanded
http://api.example.com/purchase/1?expand=orderItem
or a single one
http://api.example.com/purchase/1?expand=orderItem[0]
You can get more advanced like the examples you've already listed (nested entities, sibling entities).
Once you've implemented and used in production and see how it works in practice, you should write up a pull request to kevinswiber/siren so there can be some standardization on how a siren based API communicates support for such a feature.
Looking forward to seeing how it turns out.
Just a comment for now...still needs follow up...
Something to keep in mind here is that some requests are sent to the server for parsing and other requests we want parsed on the client.
For example, lets say you make the following request:
http://api.example.com/purchase/1?expand=orderItem
The server then knows to expand the entity that matches "orderItem"
However, there are some use cases where you might want to have the client handle this, and so you would do:
http://api.example.com/purchase/1#expand=orderItem
In this case, the client is requesting http://api.example.com/purchase/1
from the server, and then once that is received, making another request to expand orderItem
Mainly jotting this down as a note for myself when I come back to this at some point...
Some more jotting down, will have to follow up on the Siren mailing list...
In order to be able to iterate recursively down the entity chain, I had been thinking we could do (I'm using the >
here to show nesting, however, I think its an illegal url character, I'm using it mainly to illustrate the concept for now**):
api.io/expand?one>two>three>four
However, this could be confusing as it's not in nama/value format and would be difficult to identify if there were more properties in the query string.
So instead we could do:
api.io/entity?expand=one>two>three>four
//or for client side parsing (for the rest of these examples the `?` and `#` can be used interchangeably):
api.io/entity#expand=one>two>three>four
If you want to expand more than one sub-entity:
api.io/entity?expand[]=one&expand[]=another&expand[]=yet-another
If you want to expand an entity within a collection:
api.io/entity?expand[]=[2]&expand[]=[3] // expands items 2 and 3 in the collection
You could even combine the two:
api.io/entity?expand[]=one>two>three&expand[]=another&expand[]=more
There could even be an expandAll:
api.io/entity?expandAll=true
While not as "pretty" as I had hoped by having the references look more like html anchors with multiple hashes (eg, #one#two#three), this way is more robust and allows client side format to mirror that of the server side format. (because the links are now valid urls)
**All my use-cases thus far have been using the sub-entities "name". However, there are times where it might be useful to use the "rel" and/or "class" of the sub-entity. If so, it would probably make sense to standardize on 3 different prefixes. Imagine something like @name
, !rel
and .class
. Note that as this can eventually get complicated and need some spaces, url encoding might be required
ok, one final thought here.
In trying to keep parity between client and server when parsing these urls, we need to address the end result of these requests.
When you request api.io/entity#expand=one>two>three>four
, is your request resolved with
1) the root entity
or
2) one of the sub-entities
I'm thinking the result would resolve with the root entity, and having it contain all the sub-entities according to the "expand" rules.
If we do this, we need another query parameter name for those times that you want the request resolved to the sub-entity (I've actually found this to be the more common use-case). For this, we can use "select" instead of "expand", and it MUST NOT be an array:
api.io/entity#select=one>two>three>four
Note that if "select" is used, a server which implements this will need to ignore any "expand" that is set in the same request.
Following up on the deep linking feature proposed in #16.
This feature his has been super useful and while I haven't documented it yet, this is what the API currently looks like:
I'd like to build on this by (in sequence):
Item 1 can be addressed by splitting the url into a "url" and a "selector" (Also, calling it "deep linking" is not accurate, its probably better described as "traversal")
Or, alternatively:
A server might even be able to support something like this via a query parameter.
Item 2 can be addressed by simply accepting an array of the entity resource urls and selectors
Item 3 can be done using js notation: