Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API nested resources should be handled by which controller?

Let's say I have a REST API endpoint: users/123/orders/234.

As the URI implies, I am returning order 234 for user 123. My question is, which controller should handle the request?

Should it be an action in the UsersController, something like GetOrder(int userId, int orderId)? Or should it be handled in the OrdersController with something like GetOrder(int id)?

Is it just a matter of taste, or is one way more "correct" than the other?

like image 472
Diego Barros Avatar asked May 15 '13 04:05

Diego Barros


People also ask

What are REST API controllers?

RestController is a Spring annotation that is used to build REST API in a declarative way. RestController annotation is applied to a class to mark it as a request handler, and Spring will do the building and provide the RESTful web service at runtime.

What is the recommended term used to refer to multiple resources in API?

In this case, we refer to these resources as singleton resources. Collections are themselves resources as well. Collections can exist globally, at the top level of an API, but can also be contained inside a single resource. In the latter case, we refer to these collections as sub-collections.

What are nested resources?

Nesting resources provide REST API consumers an easy and efficient way to manage data by allowing the consumer to send and receive only the required object. The nested resource must be a business object, that is, it must still represent a complete business object.

What should a API controller do?

The [ApiController] attribute applies inference rules for the default data sources of action parameters. These rules save you from having to identify binding sources manually by applying attributes to the action parameters.


1 Answers

Well I would advocate you should go by the entity that is being fetched.

In your case What is being fetched? : Orders -> So OrdersController.

If Users were being fetched given a particular order id then it would be a UsersController.

You should have a look at the stackexchange api for good examples : http://api.stackexchange.com/docs

There are numerous actions, but they're each grouped by the entity they operate on, and I bet that's the controller they are in.


There is no inbuilt setup for this route. You could do the following :

This is a specific route.

routes.MapHttpRoute(
    name: "users_orders",
    routeTemplate: "api/{controller}/{user_id}/Orders/{order_id}",
    defaults: new
    {
        controller = "Orders",
        action = "FetchByUser"
    });

Which would need an action method like this:

public ActionResult FetchByUser(int user_id, int order_id)
{
}

You could try doing a more generalised route like this:

routes.MapHttpRoute(
    name: "fetch_route",
    routeTemplate: "api/{controller}/{id1}/{type}/{id2}",
    defaults: new
    {
        action = "Fetch"
    });

And the action method would be:

public ActionResult Fetch(int user_id, string type, int order_id)
{
}

Note: I would interpret this -> users/123/orders/234 as for the user 123 get the order 234. If like @karan says you don't need the user context then you should not have this method. I'm not sure about your design or requirements here.

like image 129
gideon Avatar answered Oct 19 '22 23:10

gideon