Web API服务设计

时间:2012-11-27 09:58:57

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

我对Asp.NET MVC控制器在设计服务时的工作方式非常满意。 但是新的WebAPI控制器。我该怎么设计我的服务?

让我们说我们有3种不同的方式列出,例如用户。

获取最新信息,获取所有信息,获取无效状态或其他信息。

这些都不需要参数。那你将如何在WebAPI中解决这个问题

IEnumerable<User> Get10Latest()
IEnumerable<User> GetAll()
IEnumerable<User> GetInactive()

由于它们具有相同的param签名,因此无效。 那么在这里设计这个的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

通过使用action参数,您可以在一个控制器中为单个HTTP方法支持多种方法 E.g。

public class UsersController : ApiController
{

    [ActionName("All")]
    public HttpResponseMessage GetAll()
    {
        return new HttpResponseMessage();
    }

    [ActionName("MostIQ")]
    public HttpResponseMessage GetMostIQ()
    {
        return new HttpResponseMessage();
    }

    [ActionName("TenLatest")]
    public HttpResponseMessage GetTenLatest()
    {
        return new HttpResponseMessage();
    }

}

不幸的是,我还没有办法让一个控制器同时处理和不处理动作。

e.g。

public class UsersController : ApiController
{

    [ActionName("")]  // Removing this attribute doesn't help
    public HttpResponseMessage Get()
    {
        return new HttpResponseMessage();
    }

    [ActionName("All")]
    public HttpResponseMessage GetAll()
    {
        return new HttpResponseMessage();
    }

    [ActionName("MostIQ")]
    public HttpResponseMessage GetMostIQ()
    {
        return new HttpResponseMessage();
    }

    [ActionName("TenLatest")]
    public HttpResponseMessage GetTenLatest()
    {
        return new HttpResponseMessage();
    }

}

能够将单个控制器用于集合资源及其所有子集都很不错。

答案 1 :(得分:0)

有人可能会继续为此包裹我,但你需要配置你的路由以处理获取。这就是我使用上述操作的方法:

config.Routes.MapHttpRoute(
            name: "CustomApi",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { id = RouteParameter.Optional }
        );

所以现在你的请求被映射到正确的控制器 - &gt;通过路线模板行动。请注意,需要首先在WebApiConfig.cs中注册新路由。如果你保留旧的,默认的。

修改

重新阅读这个问题,我意识到我并没有完全回答设计问题。我认为从REST的角度来看,一种方法是使用一个单独的资源来公开正确的集合(例如Get10Latest),因为我认为有一个商业原因可以通过公开数据的确切子集服务。在这种情况下,您将通过其自己的Controller中的单个Get公开该资源(如果这是所需的行为)。

答案 2 :(得分:0)

为什么没有这样的网址:

GET /users
GET /users/latest
GET /users/inactive

使用路由可以将它们路由到

public classs UserController : ApiController
{
    public IEnumerable<User> Get(string mode)
    {
        // mode is in routing restricted to be either empty, latest, or inactive
     }
 }

否则使用多个控制器。在Web API中使用动作名称是一种错误的方式。