REST: One to Many for GET via a foreign key - api

Relationships
robot has many brains
brain has one robot
Background
How to form the resource URL where we provide a robotId (foreign key) to retrieve its brain?
I could come up with this resource:
GET /robots/:robotId/brain
I am not sure if using brain in singular is against REST conventions and practices.
However, using GET /robots/:robotId/brains (brain in plurals) implies a collection will be returned but it will always have 1 item only.
Question
Can you advise me on a RESTful way?

Can you advise me on a RESTful way?
REST doesn't care what spelling conventions you use for your resource identifiers.
Therefore, you should use whatever spellings make sense within your local context. That might mean, for your own convenience, that the spelling conventions that you use for your path segments are similar to those that you use when naming collections/tables in your data store. Or perhaps not - you could equally decide that, because the audiences differ, so too should the spelling conventions.
GET /robots/:robotId/brain
GET /robots/:robotId/brains
GET /brains/:robotId
GET /ee4fcf74-d494-4f90-8964-9e4d65aa61ef
These are all fine.
Stefan Tilkov's 2014 talk: REST: I don't Think it Means What You Think it Does may be helpful.

For me, you should have only 1 endpoint GET /robots/:robotId/brains, you will get all your collection, but your frontend have to processing your data like he want

If you have GET /robots/:robotId/brains this can still return a collection of size 1?

You should have a rest end point which gives you the collection of all the brains of a robot. The uri should look like this :
GET /robots/:robotId/brains
Number of items the collection has should not matter.
If the rest end point is GET /robots/:robotId/brain, you are very much ignoring the fact that a robot might have multiple brains in the future and if very much possible if you database supports a one to many relationship.
To get 1 brain of a robot you can always keep scope for the below rest uri: GET /robots/:robotId/brains/:brainId Where brainId is the unique/primary key for a brain.

Related

best practive rest api method get with many parameters

i have question similar to this article ( Multiple optional query string parameters REST API GET ) but the given answers have 3 different opinion/answer and i dont know which one is the best practice to use, ive searched everywhere but cant find the definite answer.can someone please help me which answer is the right one and has a prove(trusted source that backing it up) that it is a best practice, sorry for bad english i hope you can understand what im saying,
The best way is to add filters in get request. Response in this post gives one example -
Best practice for filtering results from a RESTful API call?
In rest everything is a resource so if you want to filter items within same resource you can pass filter criteria along with pagination parameters. Generally only for separate resources we create a new API for optional parameters or to filter within same resource separate APIs should not be created. They are additional testing and maintenance cost.
To me answer #2 in the article makes most sense. You will be ok going with it

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

How to organize REST 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?

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.

Unique identifiers for each resource in RESTful API?

In an ideal RESTful API that supports multiple accounts, should each resource have it's unique identifier across the entire system, or it is OK if that identifier is unique for the specific account that it belongs to.
Are there any pros and cons for each scenario?
To give an example.
Would this be fine from the REST principles?
http://api.example.com/account/1/users/1
...
http://api.example.com/account/50/users/1
or would this approach be recommended?
http://api.example.com/account/1/users/{UNIQUE_IDENTIFIER}
...
http://api.example.com/account/50/users/{ANOTHER_UNIQUE_IDENTIFIER}
You reveal valid user numbers by always having the first user as 1. Someone then knows that any account will also have a user 1. I'm not saying that you should hide user IDs just through obscurity but why make it easy for someone to find the user IDs in another account?
All that really matters is that each resource has a unique identifier. Both of your examples accomplish that, so you seem to be okay (RESTfully speaking)
I don't see any compelling reason to use one over the other. I'd choose whatever makes more sense for your implementation.
Since, from the perspective of an external system using your REST API, the entire address should be considered to be the "identifier" for that resource object, so your first example is fine.