Backbone.js & REST API resources relationship & interraction - rest

I have a small REST API that is being consumed by a single page web application powered by Backbone.js
There are two resource types that the API provides, and therefore, the Backbone app uses. These are articles and comments. These two resources have different endpoints and there is a link from each of the articles to the location of all the comments for that item.
The problem that I'm facing is that, on the article list in my web app I would like to be able to display the number of comments for each article. Given that that would only be possible if I also get the comments list, on the current setup, would require me to make one API request to get the the initial article list and another one for each of the articles to be able to count the number of comments. That becomes a problem if, for instance, there are 100 articles, and therefore 101 HTTP requests would be necessary to populate one single view.
The solutions I can think of right now are:
1. to include the comments data in the initial articles request like so
{
{
"id": 1,
"name": "Article 1",
...
"comments": {
{
"id": 1,
"text": "some comment"
},
{
"id": 2,
"text": "some comment"
},
...
}
},
}
The question in this case is: How is it possible to parse the "comments" as a separate comments collection and not include it into the article model?
2. to include some metadata inside the articles response like so:
{
{
"id": 1,
"name": "Article 1",
...
"comments": 13
},
}
Option that raises the question: how should I handle the parse of the model so that, on one hand the meta information is available, and on the other hand, the "comments" attribute is not one Backbone would try to perform updates on?
I feel there might be another solution, compliant with the REST philosophy, for this that I'm missing, so if you have any other suggestion please let me know.

I think your best bet is to go with your second option, include the number of comments for each article inside your article model.
Option that raises the question: how should I handle the parse of the model so that, on one hand the meta information is available, and on the other hand, the "comments" attribute is not one Backbone would try to perform updates on?
Not sure what your concern is here. Why would you be worried about the comments attribute getting updated?
I can't think of any other "RESTy" way of achieving your desired result.

I would suggest using alternative 2 and have the server return
a subset of the article attributes that are deemed useful for
applications when dealing with the article collection resource
(perhaps reachable at /articles).
The full article member resource with all its comments (whether
they are stored in separate tables in the backend) would be
available at /articles/:id).
From a Backbone.js point of view you probably want to put the
collection resource in a, say, ArticleCollection which will
convert each member (currently with a subset of the attributes)
to Article models.
When the user selects to view an article in full you pull it
out from the ArticleCollection and invoke fetch to populate
it in full.
Regarding what to do with extra/virtual attributes that are included
in the collection resource (/articles) like the comment count and
possibly other usefult aggregations, I see a few alternatives:
In Article#initialize you can pull those out from the attributes
and store them as meta-data on the article. This way the built-in
Backbone.Model#toJSON will not see them.
Keep them in the attributes section of each model and override
Backbone.Model#toJSON to exlcude them when "serializing" an Article.
In atlernative 1, an Article#commentCount() helper could return
this._commentCount || this.get('comments').length to make it work
on both partially and fully loaded articles.
For a fully loaded Article you would probably want to convert the
nested comments array into a full-blown CommentCollection anyway
and store that in this._comments so I don't think it is that unusual
to have your models store additional stuff directly on the model instance,
outside of its attributes hash.

Related

REST endpoint design for retrieving results in many to many relationship

I have read many of the other posts on designing many to many relationships restfully; however, i couldn't quite found the answers i was looking for.
Basically, I have 2 tables in the database and another many-to-many table that bridges these 2 tables.
For simplicity lets call them:
Course(CourseID, CourseName)
Instructor(InstructorID, InstructorName)
CourseInstructor(CourseID, InstructorID, lectureRoomName) (MANY-TO-MANY)
I have 2 questions:
1) How should I get all the entries inside the CourseInstructor table.
Is GET /courses/instructors correct? (or GET /instructors/courses or both)
Or should I have a seperate endpoint called /coursesinstructors
2) Also I want to be able to get all rows in the CourseInstructor table by passing in CourseName.
Normally i think i would do, /courses?name=coursename if i was searching for a course. And, I might use the endpoint /courses/{courseId}/instructors/{instructorId} to search for a specific entry in the many-to-many table.
Thus, I am curious would something like this work: /courses?name=coursename/instructors (Is this even possible?)
Another alternative is to have another endpoint called /coursesinstructors and i can make /courseinstructor?name=coursename to get the results.
Or should i make 2 calls to get the results by doing:
- get the id through /courses?name=coursename
- and follow it with courses/{id}/instructors
I am open to any other suggestions and solutions other than the ones I came up with above (not sure mine are correct solutions anyways).
For the first scenario, it really depends on what your use cases are. GET /courses/instructors would imply (only) retrieving the instructors, so I'd personally go with just GET /courses, and embed the instructors.
As for the second scenario, /courses?name=coursename should be good enough (plus /courses/{courseId}/instructors/{instructorId} for drilling down to a specific entry). The 2 calls is another valid option. However, an URL like /courses?name=coursename/instructors doesn't seem to be valid, according to RFC 3986.
If you really do need (1), a full dump of all course-instructor pairings, then I think your best bet is to support
GET /course-instructors
GET /course-instructors?courseName=whatever
You can then either link to or embed the course and the instructor.
{
"course": "/courses/12",
"instructor": "/instructors/54"
}
{
"course": {
"name": "Political Science",
...
},
"instructor": {
"name": "Hober Mallow",
...
}
}
What you return depends on the needs of your clients. Perhaps you return abbreviated information plus a link to the full representation, or perhaps it's ok to return just the links because courses and instructors are (should be!) highly cacheable.
As an aside, I think you'd be well-served to stop thinking about how the database stores data, and rather think about what clients need from your API.

How do you model a RESTful API for a single resource?

I am looking to expose some domain RESTful APIs on top of an existing project. One of the entities I need to model has a single document: settings. Settings are created with the application and is a singleton document. I'd like to expose it via a well-designed resource-based RESTful API.
Normally when modeling an API for a resource with many items its something like:
GET /employees/ <-- returns [] of 1-* items
GET /employees/{id}/ <-- returns 1 item
POST /employees/ <-- creates an item
PUT /employees/{id}/ <-- updates all fields on specific item
PATCH /employees/{id}/ <-- updates a subset of fields specified on an item
DELETE /employees/{id}/ <-- deletes a specific item
OPTION 1: If I modeled settings in the same way then the following API is built:
GET /settings/ <-- returns [] of 1-* items
[{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }]
GET /settings/{id}/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/{id}/
PATCH /settings/{id}/
This to me has a few nuances:
We return an array when only 1 item CAN and EVER WILL exist. Settings are a singleton that the application creates.
We require knowing the id to make a request only returning 1 item
We require the id of a singleton just to PUT or PATCH it
OPTION 2: My mind then goes in this direction:
GET /settings/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/
PATCH /settings/
This design removes the nuances brought up below and doesn't require an id to PUT or PATCH. This feels the most consistent to me as all requests have the same shape.
OPTION 3: Another option is to add the id back to the PUT and the PATCH to require it to make updates, but then an API user must perform a GET just to obtain the id of a singleton:
GET /settings/ <-- returns 1 item
{ "id": "06e24c15-f7e6-418e-9077-7e86d14981e3", "property": "value" }
PUT /settings/{id}/
PATCH /settings/{id}/
This seems inconsistent because the GET 1 doesn't have the same shape as the UPDATE 1 request. It also doesn't require a consumer to perform a GET to find the identifier of the singleton.
Is there a preferred way to model this?
Does anyone have any good reference material on modeling RESTful APIs for singleton resources? I am currently leaning towards OPTION 2 but I'd like to know if there are good resources or standards that I can look into.
Is there a compelling reason to require an API consumer to make a GET for the id of a resource to then use it in an update request, perhaps for security reasons, etc?
The ID of the Resource is the Url itself and not necessarily a Guid or UUID. The Url should uniquely IDentify the Resource, in your case the Settings entity.
But, in order to be RESTfull, you must point to this resource in your index Url (i.e. the / path) with an appropriate rel attribute, so the client will not hardcode the Url, such as this:
GET /
{ ....
"links": [
{ "url" : "/settings", "rel" : "settings" }
], ...
}
There are no specifics to accesing a singleton resource other than the Url will not contain a Guid, Uuid or any other numeric value.
Option 2 is perfectly RESTful, as far as I can tell.
The core idea behind RESTful APIs is that you're manipulating "resources". The word "resource" is intentionally left vague so that it can refer to whatever is important to the specfic application, and so that the API can focus only on how content will be accessed regardless of what content will be accessed.
If your resource is a singleton, it does not make sense to attribute an ID value to it. IDs are very useful and commonly used in RESTful APIs, but they are not a core part of what makes an API RESTful, and, as you have noticed, would actually make accessing singleton resources more cumbersome.
Therefore, you should just do away with IDs and have both
GET /settings/
and
GET /settings/{id}
always return the settings singleton object. (access-by-id is not required, but it's nice to have just in case someone tries it). Also, be sure to document your API endpoint so consumers don't expect an array :)
Re: your questions,
I believe option 2 would be the preferred way of modeling this, and I believe requiring your consumer to make a GET for the id would actually be somewhat of an anti-pattern.
I think the confusion here is because the word settings is plural, but the resource is a singleton.
Why not rename the resource to /configuration and go with option 2?
It would probably be less surprising to consumers of your API.
You're probably overthinking it. There's no concept of singleton in HTTP or REST.
GET /settings/ is perfectly fine.
By the way, we can hardly relate this to DDD - at least not if you don't give more context about what settings means in your domain.
It might also be that you're trying to tack an "Entity with ID" approach on Settings when it's not appropriate. Not all objects in a system are entities.

RESTful way to ask for subset of a resource

Suppose I have a resource called user_stats, that has things like how many posts, comments, likes, and followers users have. Is there a RESTful way to only ask for parts of that statistics (i.e. for user_stats/3, tell me how many posts and comments this user has, but don't tell me how many follower this user has.)
The reason I'm asking is some statistical attributes can be computationally intensive (yes I'm generating them at query time). So simply not asking for it can reduce workload.
There is a very useful 38 page free ebook with best practices about designing Web APIs, you might find it helpful, at least I did.
For your case, it is stated:
Add optional fields in a comma-delimited list
The Google approach works extremely well.
Here's how to get just the information we need from our dogs API using
this approach:
/dogs?fields=name,color,location
It's simple to read; a developer can select just the information an
app needs at a given time; it cuts down on bandwidth issues, which is
important for mobile apps. The partial selection syntax can also be used to include associated resources cutting down on the number of requests needed to get the required information.
Maybe that's what you re looking for?
there are at least three options:
Use query parameter as a filter
e.g. user_stats?fields=posts,comments
Make user_stats composite resource and create new resources for particular stat
e.g. /user_stats in JSON
{
"blogs" : {
"count" : 10,
"link" : "/user_stats_blobs"
},
...
}
then you can get whole stats (GET /user_stats) or just a piece (GET /user_stats_blobs)
Create filter representation; use POST to post filter representation as part of request
e.g.
Request
POST /user_stats/filter
{
"fields" : [ "blogs", ...]
}
response body contains just requested/filtered data.
All solutions are RESTful. Solution 1. is easy to implement but has limited extensibility and transparency. Solution 2. expects that you create new resources which is overhead in this case (you need just one number). so, I would recommend solution 3. because is no so hard to implement, is easily extensible and transparent.

HATEOAS - Discovery and URI Templating

I'm designing a HATEOAS API for internal data at my company, but have been having troubles with the discovery of links. Consider the following set of steps for someone to retrieve information about a specific employee in this system:
User sends GET to http://coredata/ to get all available resources, returns a number of links including one tagged as rel = "http://coredata/rels/employees"
User follows HREF on the rel from the first request, performing a GET at (for example) http://coredata/employees
The data returned from this last call is my conundrum and a situation where I've heard mixed suggestions. Here are some of them:
That GET will return all employees (with perhaps truncated data), and the client would be responsible for picking the one it wants from that list.
That GET would return a number of URI templated links describing how to query / get one employee / get all employees. Something like:
"_links": {
"http://coredata/rels/employees#RetrieveOne": {
"href": "http://coredata/employees/{id}"
},
"http://coredata/rels/employees#Query": {
"href": "http://coredata/employees{?login,firstName,lastName}"
},
"http://coredata/rels/employees#All": {
"href": "http://coredata/employees/all"
}
}
I'm a little stuck here with what remains closest to HATEOAS. For option 1, I really do not want to make my clients retrieve all employees every time for the sake of navigation, but I can see how using URI templating in example two introduces some out-of-band knowledge.
My other thought was to use the RetrieveOne, Query, and All operations as my cool URLs, but that seems to violate the concept that you should be able to navigate to the resources you want from one base URI.
Has anyone else managed to come up with a good way to handle this? Navigation is dead simple once you've retrieved one resource or a set of resources, but it seems very difficult to use for discovery.
Option 2 is not too bad as you're using RFC 6570 to characterize the URI patterns; while HATEOAS is usually stated in terms of not having clients synthesize URIs, if a server is prepared to make guarantees on the URI template and to tell it to clients explicitly in a standard format, it's acceptable. (I would be tempted to have the “list all employees” URL be without the all suffix, so as to distinguish it from the employee with that ID; the client should not — in principle — know what an employee ID looks like.)
In fact, the main problem is actually that clients have to understand what those tag URIs mean; there's just no real way to guess that “http://coredata/rels/employees#All” means “list all employees”. That's where you get into embedding knowledge in clients, semantic labeling, etc. and HATEOAS doesn't really address those things.
TL;DR: Use OPTIONS method to return programmatically consumable documentation and always implement pagination.
We create a number of internal REST services at my work. We have standardized on the use of the OPTIONS method to return the metadata of a resource. The metadata we return acts a parsable documentation of that resource. It indicates url templates, various options such as PAGE, PAGESIZE and the different methods that the resource supports. We also return rel links so top level resource discovery can occur with the use of OPTIONS without pulling and actual data.
We also implement pagination specifically to prevent issues around returning large amounts of data unnecessarily.
My HATEOAS API returns HTML as well as HAL+JSON, as you are using, and they both use the same URIs, so my JSON responses simply return what a human web user would see (minus all the pretty colours). e.g.
GET /
{"_links": {
"http://coredata/companies": { "href": "/companies?page=1" }
...
}}
GET /companies?page=1
{"_links": {
"next": { "href": "?page=2" }
...
}}

REST API Design links between collections of resources

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.
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
The combination of methods 1 and 2 looks good, as you say in method 2, don't have too much sense create comments without a document context since a parent child relationship exists between both, if you delete a document is acceptable to delete all his comments also, you can make your/comments/ uri a read-only resource in order to avoid his creation without a document.
As filip26 says rest apis should be hypermedia driven but that not means that the url patterns aren't important, you could have a resource with one uri or many, if your resources have multiple uris is easier for clients to find them, the downside is that could be confusing because some clients use one uri instead of another, so you can use a canonical uri for a resource, when a client access a resource throught this canonical uri you can send back a 200 OK, when a client request one of the others uri you can send back a 303 "See also" along with the canonical uri.`