How to organize REST API? - api

I'm developing a rest API for our business system. We have the following resources so far:
/sales/orders
/sales/orders/{orderno}
/sales/order-items
There will be lots of resources when the API is finished, so we need to structure it in a good way to make it easy to understand. My question is: should /sales/order-items instead be /sales/orders/order-items? There is maybe no correct answer here, but what would you prefer?
One more question: The sales/order-items resource will list either all open items or all shipped items. It will not be possible to get all order-items regardless of status (open/shipped). The resource URI could the be like this sales/order-items?orderstatus={OPEN/SHIPPED} (the orderstatus query parameter would be mandatory then) or it could be two resources like this sales/order-items/open and sales/order-items/shipped. What is the preferred?

A resource is 'any information that can be named'. Your URIs should be entity based. 'order-items' is not an entity, but a data type.
/sales/order/order-1456321 is the Entity you most likely want. Which would contain the data of all order items.
If you wish to restrict access, you can return a client error if no query string is supplied. and having
/sales/order/order-12345?status=open
etc. Hope this helps.
EDIT:
/sales/order-items or /sales/orders/order-items?
This is domain specific, and really should be answered by a domain expert. Your URI Hierarchy provides scope (and so detail) to your resource. So as an educated guess, It does not make sense to have "order-items" within the scope of "/sales/orders/" because "order-items" is not an "order".
/sales/ordered-items
seems the most sensible answer.
On a personal note, and not to question your domain too much, Having a strong understanding of the flow of the business and information that's stored may result in something along the lines of these suggestions;
/sales/orders?status=open - Are all orders shipped at once?
/sales/orders/order-1234/packages?status=open - Are orders split into packages?

Related

API - do I need the parent resource?

A person can have many reviews. My endpoint to CREATE a new review is:
post /person/{id}/reviews
How about the endpoint to UPDATE a review? I see two options:
Stick to the parent resource: patch /person/{person_id}/reviews/{id}
Only have reviews in the URI: patch /reviews/{id}
I could be sold on using either of them:
It's consistent with the previously defined endpoint, but {person_id} is not needed.
It's 'efficient' as we're not specifying a parameter ({person_id}) that is not really needed. However, it breaks the API convention.
Which one is preferable and why?
The client shouldn't have to know about ids at all. After a client creates the review, the response should include the URI to the new review like this:
HTTP/1.1 201 Created
Location: /person/4/reviews/5
The client now has the full URL to the review, making it completely irrelevant how it looks like and what information is here.
Don't forget that the URL itself is a system to create globally unique IDs, that embed not just it's own unique identity but also information on how to access the data. If you introduce a separate 'id' and 'person_id' field you are not taking advantage of how the web is supposed to work.
In terms of API design, without knowing too much detail about OP's situation I'd walk along these guideposts:
Only have reviews in the URI: patch /reviews/{id}
It's 'efficient' as we're not specifying a parameter ({person_id})
that is not really needed. However, it breaks the API convention
The "efficiency" allows for a more flexible design. There's no existing API convention broken at this point. Moreover, this approach gives you the flexibility to avoid the need of always needing the parent resource ID whenever you display your items.
Stick to the parent resource: patch /person/{person_id}/reviews/{id}
It's consistent with the previously defined endpoint, but {person_id}
is not needed.
The consistency aspect here can be neglected. It's not beneficial to design endpoints similarly to other endpoints just because the previous ones were designed in a certain way.
The key when deciding one way or the other is the intent you communicate and the following restrictions that are put on the endpoint.
The crucial question here is:
Can the reviews ever exist on their own or will they always have a parent person?
If you don't know for sure, go for the more flexible design: PATCH /reviews/{id}
If you do know for sure that it always will be bound to a particular person and never can have a null value for person_id in the database, then you could embed it right into your endpoint design with: PATCH /person/{person_id}/reviews/{id}
By the way, the same is true for other endpoints, like the creation endpoint POST /person/{person_id}/reviews/{id}. Having an endpoint like this removes the flexibility of creating reviews without a person, which may be desirable or not.

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.

User friendly and restful (rails 3)

i am a rails programmer who is on to his 3rd project now (new of course).I am looking for an answer to a general question about Restful architecture. I am sure i am doing something that has a good established answer already.
In restful approach we expose resources but some times this approach feels a little Non user friendly. For example i can expose a product via a show method and then i have another resource called sales that i can expose via product/:id/sales show template to show all sales for a product. But i am taking the user through an extra click here. The ideal will be to show product and all its associated sales on one page itself. But that is a violation of the Restful rule.
I just wanted to ask that are these rules generally broken to make the site user friendly? Being a new comer i dont want to adopt ways that are non ideal so i thought i should ask this question.
Thanks in advance.
Adding in the sales for a particular product would not be breaking any constraints from the RESTful architecture. You have the product ID in the HTTP request so you can just also get the sales for that product. Your separation of concerns should not be affected and you don't need to store a state to get this information. Just extend the model that you return with the view.
It seems like you are more concerned with straying from the convention over configuration that Rails promotes. This extension means that your model will not correlate with only one table in your database, but that is fine. The conventions are meant to reduce the configuration work that you need to do, not restrict your functionality.

designing a restful api: naming URIs, custom headers?

EDIT: I've solved my issues (for now at least).
I've recently been working with the Zendesk REST Api and their use of the custom "X-On-Behalf-Of" header for looking up tickets opened by a particular user got me thinking about Restful Api design choices (in no specific language, more of a how to name URIs question). I've also read this related question on Custom HTTP headers, but it left me with more questions than answers.
Say I have an example restful web service dealing with rental apartment applications where clients use Basic Auth (keep it simple) to authenticate. Define the basic data as such:
Users (can be of type landlord or renter)
Forms (which consist of one or more Document resources and some form meta data like form name and version info)
And then some type of resource corresponding to Rental Applications, which ties together Forms, Applicants (one or more renters), Landlord, and some metadata like status and dates.
I'm struggling to properly model the URIs for the Applications resource in general, and more specifically with respect to a clients role. (assume api root is https://api.example.com/)
How do I allow a Landlord to fetch a list of applications sent to them? My intuition says make a request to "GET /applications" and Basic Auth lets the server know which user to build the list for; likewise "GET /applications" requested by a Renter would return a list of applications they've sent...but I'm not confident this is a solid design in general to mix and match sender vs. recipient lists at the same URI. Should I be thinking about the "/applications" resource differently, and perhaps allowing a hierarchy like "/applications/[USER_IDENTIFIER]" for each user instead?
Also, regardless of my applications URI design, assume a Landlord is able to create an application on behalf of a renter. Is this better accomplished by sending a custom header like "X-Create-On-Behalf-Of: somerenter#example.com" with the PUT/POST creation request? Or should my schema define a field which allows for this alternative scenario.
I'm very much an amateur at this, so I'm open to any criticism of my assumptions/design, as well as any pointers for learning more about designing RESTful api's. Thanks for reading.
I think I've found a solution.
Landlords and Renters are really just subclasses of the same object, which I'll call Party (as in party to a transaction, not birthday party). So then each one has their own resource, named like /party/PARTY_ID.
It's easy to extend this to see that /party/SOME_LANDLORD/applications and /party/SOME_RENTER/applications solve my issues. It also removes my need to consider custom headers.