假设我有一个REST API端点:users/123/orders/234
。
正如URI所暗示的那样,我正在为用户123返回234。我的问题是,哪个控制器应该处理请求?
它应该是UsersController中的一个动作,比如 GetOrder(int userId,int orderId)?或者应该在OrdersController中使用 GetOrder(int id)等处理它?</ p>
这只是一种品味问题,还是比其他方式更“正确”?
答案 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
。