I have been pondering the correct method of defining resource collections which have interdependence.
For instance, lets consider "documents" and "comments" which are independently accessible via the URI's:
/documents/{doc-uri}
/comments/{comment-id}
However, we typically want the collection of comments related to a specific document. Which creates a design question around how this should be archetected.
I can see a few main options:
1.) Supply an collection uri after the document uri for comments
GET /documents/{doc-uri}/comments/
2.) Provide a parameter to the comments collection to select by document
GET /comments/{comment-id}?related-doc={doc-uri}
3.) Use content negotiation to request the related comments be returned via the Accept header.
// Get all the comments for a document
GET /documents/{doc-uri} Accept: application/vnd.comments+xml
// Create a new comment
POST /documents/{doc-uri} Content-Type: application/vnd.comment+xml <comment>...</comment>
Method 1 has the advantage of automatically putting the comments in context of the document. Which is also nice when creating,updating and deleting comments using POST/PUT. However it does not provide global access to comments outside the context of a document. So if we wanted to do a search over all comments in the system we would need method #2.
Method 2 offers many of the same benefits as #1, however creating a comment without the context of a document makes no sense. Since comments must explicitly be related to a document.
Method 3 is interesting from a GET and POST/create perspective, but gets kinda hairy with update and delete.
I can see pro's and con's to all these methods so I am looking for some more guidance from someone who may have approached and solved this issue before.
I am considering doing both methods 1 & 2, thus I can provide all the functionality needed, but I am concerned I may be over-complicating/duplicating functionality.
Link objects are used to express structural relationships in the API. So for example, the top-level collections, singleton resources and sub-collections (including actions) are all referenced using link objects. Object links are used to express semantic relationships from the application data model.
This Account resource and every other JSON resource will always have an href property, which is the fully qualified canonical URL where that resource resides. Whenever you see an href property, you know you can access that resource by executing a GET request to the resource's URL.
Here each resource is identified by URIs/ Global IDs. REST uses various representations to represent a resource where Text, JSON, XML. The most popular representations of resources are XML and JSON.
URL Structure The recommended convention for URLs is to use alternate collection / resource path segments, relative to the API entry point.
REST API must be hypermedia-driven. See Hypermedia as the Engine of Application State (HATEOAS) constraint. So, don't waste your time on URLPatterns, because they are not RESTful. URLPattern implicates tight-coupling between a client and a server; simply, the client must be aware of how URLs look like and has an ability to construct them.
Consider this REST design for your use-case:
The representation of a document contains a link where the client can POST comments or with using of GET get all comments on the document. e.g.
{
...
"comments" : {
"href": ".. url ..",
"rel": ["create-new-comment", "list-comments"]
}
}
A client just takes this URL and performs GET or POST method on the URL; without a knowledge how the URL is, looks like.
See also this post:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With