具有关联的 RESTful Web API。是否可以?

标签 rest asp.net-web-api asp.net-web-api-routing

我已经使用 Web API 编写了一个 REST 服务,并且在阅读了本 Web API Design 的部分之后来自 Brian Mulloy,他试图弄清楚如何实现与 Web API 的关联。

Web API 设计摘录:

Associations

Resources almost always have relationships to other resources. What's a simple way to express these relationships in aWebAPI?

Let's look again at the API we modeled in nouns are good, verbs are bad -theAPI that interacts with our dogs resource. Remember, we had two base URLs: /dogs and dogs/1234.

We're using HTTP verbs to operate on the resources and collections. Our dogs belong to owners. To get all the dogs belonging to a specific owner, or to create a new dog for that owner, do a GET or a POST:

GET /owners/5678/dogs
POST /owners/5678/dogs

Now, the relationships can be complex. Owners have relationships with veterinarians, who have relationships with dogs, who have relationships with food, and so on. It's not uncommon to see people string these together making a URL 5 or 6 levels deep. Remember that once you have the primary key for one level, you usually don't need to include the levels above because you've already got your specific object. In other words, you shouldn't need too many cases where a URL is deeper than what we have above /resource/identifier/resource.



所以我尝试为关联添加一个 Controller 方法,如下所示:
public class EventsController : ApiController
{
    // GET api/events
    public IEnumerable<Event> Get()
    {
        // get list code
    }

    // GET api/events/5
    public Event Get(int id)
    {
        // get code
    }

    // POST api/events
    public void Post([FromBody]Event evnt)
    {
        // add code
    }

    // POST api/events/5
    public void Post(int id, [FromBody]Event evnt)
    {
        // update code
    }

    // DELETE api/events/5
    public void Delete(int id)
    {
        // delete code
    }

    // GET api/events/5/guests
    public IEnumerable<Guest> Guests(int id)
    {
        // association code
    }
}

我还将我的路线模板修改为以下内容:
config.Routes.MapHttpRoute("ApiWithAssociations",
                           "api/{controller}/{id}/{action}");
config.Routes.MapHttpRoute("DefaultApi",
                           "api/{controller}/{id}",
                           new { id = RouteParameter.Optional });

不幸的是,当我更新/发布事件资源时,我现在收到一个 HTTP 500 内部服务器错误,响应正文说明

Multiple actions were found that match the request



我已经尝试在添加 System.Web.Http.HttpPostAttribute(和其他 HTTP 动词)的同时修改路由模板,但无济于事。

有没有人试过这个并让它工作?任何帮助,将不胜感激。如果绝对不可能有多个 http 动词,那么我想我将不得不放弃与我的 REST 服务的关联。

编辑:解决方案

使用 Radim Köhler 的回答,我能够完成这项工作。将 HttpGetAttribute 添加到 guest 方法中,如下所示:
// GET api/event/5/guests
[HttpGet]
public IEnumerable<Guest> Guests(int id)
{
    // association code
}

并添加了一个附加路由来满足默认的 GET 操作,如下所示:
config.Routes.MapHttpRoute("DefaultGet",
                            "api/{controller}/{id}",
                            new {action = "Get"},
                            new {httpMethod = new HttpMethodConstraint(HttpMethod.Get)});
config.Routes.MapHttpRoute("ApiWithAssociations",
                            "api/{controller}/{id}/{action}");
config.Routes.MapHttpRoute("DefaultApi",
                            "api/{controller}/{id}",
                            new {id = RouteParameter.Optional});

最佳答案

解决方案可能是在显式的 POST 映射中

只需添加新定义,它将用于 events/5 POST

// explicit Post() mapping 
config.Routes.MapHttpRoute(
    name: "DefaultPost",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Post" }
    , constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
    );

// existing
config.Routes.MapHttpRoute("ApiWithAssociations",
    "api/{controller}/{id}/{action}");
config.Routes.MapHttpRoute("DefaultApi",
    "api/{controller}/{id}",
    new { id = RouteParameter.Optional });

关于具有关联的 RESTful Web API。是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16839781/

相关文章:

python - 如何在 FastAPI 中对模型的所有字段启用过滤

python - 使用自定义装饰器/属性记录 Python Bottle API

c# - 在 ASP.NET WebApi 2 中为移动应用程序实现外部身份验证

asp.net-mvc - 如何从 HttpAuthenticationContext 获取自定义 header 值

asp.net-mvc - ApiController 中的 ASP.NET Web API 路由

javascript - Angular 和 Laravel 应该是单独的应用程序还是 Laravel 应该为 Angular 应用程序提供服务?

forms - Spring MVC Restful 应用程序 : Redirect a form result to another page

oracle - 在 Linux 上使用 Oracle Apex 安装 RESTful 服务和 Tomcat 8

c# - 多个 Controller 上的属性路由匹配请求的 url

asp.net - 您可以在 .NET WebApi Route URI 中使用正则表达式进行 API 版本控制吗