REST API design aggregate - api

We are creating api on employee manage app. So there is schedule in interface, where we have to show all shifts in table, for every user per row. Farther, there is summary for every user (per row) and day (per column). Should we create one big aggregate call like:
GET /api/locations/{id}/shedule
which will return all employees, shifts, summaries etc. Or maybe should we smash that to several collections like:
GET /api/locations/{id}/shifts
GET /api/locations/{id}/events
GET /api/locations/{id}/summary
GET /api/employee/{id}/summary?date_from={date_from}&date_from={date_to}
For me, second option is more flexible and there is no reason to create new abstract resource, which is shedule. In my opinion it is clearly part of interface layer and should not affect on API design.
On the other hand the big aggregate is more optimal, becouse there will be less database calls and it's easy to cache.
How do you think? Is there any source, kind of article, which can I rely on?

There's nothing RESTful or unRESTful about either approach. The semantics of URIs is irrelevant to REST. What really matters is how the clients obtain the URIs. If they are looking up URI patterns in documentation and filling up values instead of using links, the API is not RESTful.
With that in mind, I'd say the approach that is more consistent with your business and your ecosystem of applications is the best one. Don't be afraid to create aggregate resources if you feel the need to.

Related

Ways to handle security/authorization in a multi tenant API

I'm playing around with a spare time project, mainly to try out new stuff :)
This involves designing a REST API for a system that is multi tenant. Lets say you have an "organization" that is the "top" entity, this might have an API key assigned that is used for authenticating each request. So on each request we have an organization associated.
Now when a user of the API would like to get a list of, lets say projects, only those that belong to that organization should be returned. The actual implementation, the queries to the database, is pretty straight forward. However the approach is interesting I think.
You could implement the filtering each time you query the database, but a better approach would be a general pre-query applied to all "organization" related queries, like all queries for enities that belong to an organization. It's all about avoiding the wrong entities from being returned. You could isolate the database, but if that is not possible how would you approach it?
Right now I use NancyFX and RavenDB so input for that stack would be appreciated, but general ideas and best practices, do's and don't is very welcome.
In this case you could isolate your collections by prefixing them with the organization_id. It will duplicate maybe many collections.
Use case with mongodb: http://support.mongohq.com/use-cases/multi-tenant.html

REST best practices: should a store also return metadata?

I'm building my first REST API (at least trying) for a personal project.
In this project there are resources called players which hold can be in a team. According to REST API design rulebook a resource should be made either to be a document or a store and one should keeps these roles as segregated as possible.
Yet I would like to append some metadata to the team resource, eg the date the team was founded. Is it okay then for GET /teams/atlanta to return this metadata (making it a document) alongside the list of players in the team (making it a store).
Is this a good idea? If so why? If not why not and how to solve this better?
I know there are no rules to developing a REST API, but there are good practices and I would like to adhere to those. Please also not that this is really my first REST API so pardon my ignorance if there is any.
I would recommend having GET /teams/atlanta return just the information about the team, such as the founding date that you mention, and then having GET /teams/atlanta/players return the list of players for that team. These distinctions become more important when you are presenting an API that uses HTTP methods other than GET.
For example, if you wanted to add a player to a team - this would be a lot easier if you could just POST a player object to /teams/atlanta/players than if you had to PUT the whole team object to /teams/atlanta every time you wanted to add one individual player.
If your API only allows retrieval of data, and if it is for a specific client application, there is an argument for combining all the team data into one object to save the client having to make additional requests for the data, but bear in mind that it is less flexible.
Your application may want to display a list of teams by calling GET /teams but you probably wouldn't want all of the player information included in each object in the list as this is quite a lot of data, but if GET /teams/atlanta returns player information then it would be inconsistent not to include it in the list version too.
I would personally favour splitting up the resources as I've suggested, and live with the fact the client may need to make an extra request or two.

DDD: is it ok to contain list of entity inside an aggregate root

I am developing a client application for searching flights tickets. I have obtained a JSON with search result from server and I should express this result to client.
Suppose I have a Fare, AirlineCompany and AviaTicketSearchResult objects. AviaTicketSearchResult should contain list of AirlineCompany objects. Each AirlineCompany should contain Fares. And I guess that AviaTicketSearchResult and AirlineCompany are an Aggregate root, because I have the rule of Cascading Delete, when I delete AirlineCompany it make sense to delete all airlineCompany's fares same with AviaTicketSearchResult.
1) Is it ok to contain list of Fares inside an aggregate root (AirlineCompany)?
Another problem is that I should to have a filter ability for Fares inside AirlineCompany. Each Fare has a itinerary and every itinerary has a list of variants (ItineraryVariant) (different legs, travel etc.). When I accept the filter I should update my AirlineCompany and remove unnecessary Fares or remove unnecessary ItineraryVariant inside concrete Fare.
2) How to apply ability of filtering?
I am assuming that I should represent Fare as VO and recreate Fare object from raw data (json) each time when I apply the filter and then add it to AirlineCompany after all update AviaTicketSearchResult with filtered AirlineCompany.
I don't think that Domain-Driven Design is a good fit here. As far as I can tell you're just talking about a couple of DTOs for the UI and some means to filter them.
Domain-Driven Design comes in handy when you're trying to grasp (and model) complex behavior. View Models or DTOs should be as simple as possible. Most of the time there's no need for sophisticated and time-consuming modeling efforts.
Or, as Eric Evans puts it:
Focus on the Core Domain
1) Is it ok to contain list of Fares inside an aggregate root
(AirlineCompany)?
Yes, especially if AirlineCompany is really your aggregate root which MAY be the case. From your question, I think you might could benefit from learning more about the problem domain. Should AirlineCompany really be an aggregate root or it is just a name to the customer? Maybe Fare should really be the aggregate root and AirlineCompany should just be a string property on Fare. Be careful not to over model and focus on the problem domain. If your customer is someone purchasing tickets, I doubt that they are as focused on the AirlineCompany as they are the Fare and Itineraries. When modelling the problem domain, things like JSON and VO should be temporarily forgotten about.
2) How to apply ability of filtering?
It should be the responsibility of your repository or domain service to filter the results based on the filter parameters. The implementation of this is up to you. Generally, however, if the client is communicating to a server, the server would run the repository application code which, depending on your implementation, can pass that onto the db server allowing you to achieve the best possible performance so that you're not passing extraneous data around.

Identify item by either an ID or a slug in a RESTful API

I'm currently designing an API and I came a cross a little problem:
How should a URL of a RESTful API look like when you should be able to identify an item by either an ID or a slug?
I could think of three options:
GET /items/<id>
GET /items/<slug>
This requires that the slug and the ID are distinguishable, which is not necessarily given in this case. I can't think of a clean solution for this problem, except you do something like this:
GET /items/id/<id>
GET /items/slug/<slug>
This would work fine, however this is not the only place I want to identify items by either a slug or an ID and it would soon get very ugly when one wants to implement the same approach for the other actions. It's just not very extendable, which leads us to this approach:
GET /items?id=<id>
GET /items?slug=<slug>
This seems to be a good solution, but I don't know if it is what one would expect and thus it could lead to frustrating errors due to incorrect use. Also, it's not so easy - or let's say clean - to implement the routing for this one. However, it would be easily extendable and would look very similar to the method for getting multiple items:
GET /items?ids=<id:1>,<id:2>,<id:3>
GET /items?slugs=<slug:1>,<slug:2>,<slug:3>
But this has also a downside: What if someone wants to identify some of the items he want to fetch with IDs, but the others with a slug? Mixing these identifiers wouldn't be easy to achieve with this.
What is the best and most widely-accepted solution for these problems?
In general, what matters while designing such an API?
Of the three I prefer the third option, it's not uncommon to see that syntax; e.g. parts of Twitter's API allow that syntax:
https://dev.twitter.com/rest/reference/get/statuses/show/id
A fourth option is a hybrid approach, where you pick one (say, ID) as the typical access method for single items, but also allow queries based on the slug. E.g.:
GET /items/<id>
GET /items?slug=<slug>
GET /items?id=<id>
Your routing will obvious map /items/id to /items?id=
Extensible to multiple ids/slugs, but still meets the REST paradigm of matching URIs to the underlying data model.

The REST-way to check/uncheck like/unlike favorite/unfavorite a resource

Currently I am developing an API and within that API I want the signed in users to be able to like/unlike or favorite/unfavorite two resources.
My "Like" model (it's a Ruby on Rails 3 application) is polymorphic and belongs to two different resources:
/api/v1/resource-a/:id/likes
and
/api/v1/resource-a/:resource_a_id/resource-b/:id/likes
The thing is: I am in doubt what way to choose to make my resources as RESTful as possible. I already tried the next two ways to implement like/unlike structure in my URL's:
Case A: (like/unlike being the member of the "resource")
PUT /api/v1/resource/:id/like maps to Api::V1::ResourceController#like
PUT /api/v1/resource/:id/unlike maps to Api::V1::ResourceController#unlike
and case B: ("likes" is a resource on it's own)
POST /api/v1/resource/:id/likes maps to Api::V1::LikesController#create
DELETE /api/v1/resource/:id/likes maps to Api::V1::LikesController#destroy
In both cases I already have a user session, so I don't have to mention the id of the corresponding "like"-record when deleting/"unliking".
I would like to know how you guys have implemented such cases!
Update April 15th, 2011: With "session" I mean HTTP Basic Authentication header being sent with each request and providing encrypted username:password combination.
I think the fact that you're maintaining application state on the server (user session that contains the user id) is one of the problems here. It's making this a lot more difficult than it needs to be and it's breaking a REST's statelessness constraint.
In Case A, you've given URIs to operations, which again is not RESTful. URIs identify resources and state transitions should be performed using a uniform interface that is common to all resources. I think Case B is a lot better in this respect.
So, with these two things in mind, I'd propose something like:
PUT /api/v1/resource/:id/likes/:userid
DELETE /api/v1/resource/:id/likes/:userid
We also have the added benefit that a user can only register one 'Like' (they can repeat that 'Like' as many times as they like, and since the PUT is idempotent it has the same result no matter how many times it's performed). DELETE is also idempotent, so if an 'Unlike' operation is repeated many times for some reason then the system remains in a consistent state. Of course you can implement POST in this way, but if we use PUT and DELETE we can see that the rules associated with these verbs seem to fit our use-case really well.
I can also imagine another useful request:
GET /api/v1/resource/:id/likes/:userid
That would return details of a 'Like', such as the date it was made or the ordinal (i.e. 'This was the 50th like!').
case B is better, and here have a good sample from GitHub API.
Star a repo
PUT /user/starred/:owner/:repo
Unstar a repo
DELETE /user/starred/:owner/:repo
You are in effect defining a "like" resource, a fact that a user resource likes some other resource in your system. So in REST, you'll need to pick a resource name scheme that uniquely identifies this fact. I'd suggest (using songs as the example):
/like/user/{user-id}/song/{song-id}
Then PUT establishes a liking, and DELETE removes it. GET of course finds out if someone likes a particular song. And you could define GET /like/user/{user-id} to see a list of the songs a particular user likes, and GET /like/song/{song-id} to see a list of the users who like a particular song.
If you assume the user name is established by the existing session, as #joelittlejohn points out, and is not part of the like resource name, then you're violating REST's statelessness constraint and you lose some very important advantages. For instance, a user can only get their own likes, not their friends' likes. Also, it breaks HTTP caching, because one user's likes are indistinguishable from another's.