REST API嵌套资源应该由哪个控制器处理?

时间:2013-05-15 04:46:30

标签: asp.net-mvc rest asp.net-web-api

假设我有一个REST API端点:users/123/orders/234

正如URI所暗示的那样,我正在为用户123返回234。我的问题是,哪个控制器应该处理请求?

它应该是UsersController中的一个动作,比如 GetOrder(int userId,int orderId)?或者应该在OrdersController中使用 GetOrder(int id)等处理它?<​​/ p>

这只是一种品味问题,还是比其他方式更“正确”?

3 个答案:

答案 0 :(得分:7)

好吧,我主张你应该选择正在提取的实体

在你的情况下正在提取什么?:订单 - &gt;所以OrdersController

如果在给定特定订单ID的情况下提取用户,那么它将是UsersController

你应该看一下stackexchange api的好例子:http://api.stackexchange.com/docs

有很多动作,但它们各自按照它们所操作的实体进行分组,我打赌它们是他们所在的控制器。


此路线没有内置设置。您可以执行以下操作:

这是一条特定的路线。

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

哪个需要这样的动作方法:

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

你可以尝试做一个更通用的路线:

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

行动方法是:

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

注意:我会解释这个 - &gt; users/123/orders/234用户 123 获取订单 234 。如果@karan说你不需要用户上下文那么你就不应该有这个方法。我不确定你的设计或要求。

答案 1 :(得分:3)

我的2美分。您可以执行以下操作:

api/users/123/orders - 转到UsersController并仅检索此特定用户123的所有订单,其中api/orders,转到OrdersController将提供系统中的所有订单。

api/users/123/orders/234 - 甚至不支持这个uri空间...这里因为用户试图访问有关订单234的详细信息,所以他们应该使用api/orders/234来获取Orders控制器。

答案 2 :(得分:0)

我的意思是为这些嵌套资源使用单独的控制器,并使用默认操作名称。例如: api/users/123/orders-在UserOrdersController@index

这样,仅查看控制器名称,就可以知道路由在哪个实体上运行(在这种情况下为User),在哪个实体上被获取(在这种情况下为Order

此方法的缺点/不便之处在于,如果有一个抽象控制器,则不能使用与ModelController相同的抽象控制器。因为常规index中的ModelController没有参数,而在这种联合控制器中的index需要其操作的实体模型的id