Web API - REST帮助和澄清

时间:2015-01-01 19:28:37

标签: c# web-services rest asp.net-web-api

我正在使用WebAPI编写API,虽然我从头开始设计它,但我正在努力使其成为RESTful。在过去做Web服务工作时,我总是使用RPC模式(ASMX,SOAP等) - 例如。使用与我想要的匹配的任意方法名称。对我而言,这似乎比REST更直观和明确,但鉴于WebApi似乎更加RESTful(我知道你可以改变路线,所以它不是),我决定尝试使它成为RESTful。

我理解(我认为!)基础知识 - 例如。用于创建的POST,用于指定ID的PUT,要获取的GET,要删除的删除等等。

我的困惑是如何处理返回集合与单个对象。例如,假设我有一个名为UsersController的API控制器。据我所知,我有以下网址:

GET: /api/users (lists all users)
GET: /api/users/1 (lists details about user with ID 1)
POST: /api/users (creates a new user with details sent in the POST data)
PUT: /api/users/1 (updates the existing user with ID 1 with details sent in the POST data)
DELETE: /api/users/1 (deletes the existing user with ID 1)

对于上面的第一个网址,我还需要发送各种过滤器/搜索条件。此条件是否仅作为查询字符串参数传递?或者我应该使用完全不同的控制器来实现这种“搜索”功能?例如。 UserSearchController?如果是这样,在这种情况下应该是POST还是GET?实际上,当我写这篇文章时,我想知道一个单独的控制器是否有意义,因为我可能想要在单个用户的GET中返回比在搜索结果中更多的细节。如果同一个控制器确实为单个对象GET和GET返回一个集合返回不同的数据,它是否会使它不是RESTful?

3 个答案:

答案 0 :(得分:2)

  

对于上面的第一个网址,我还需要发送各种过滤器/搜索条件。此条件是否仅作为查询字符串参数传递?

使用查询字符串指定过滤器/搜索参数绝对有意义。

  

我是否应该使用完全不同的控制器来进行此操作"搜索"功能?例如。 UserSearchController?

你不应该这样做。我在这里看到了几个原因:

  1. GET: /api/users
  2. 中的功能几乎相同
  3. 您可以在一种方法中轻松实施GET: /api/usersGET: /api/users?filter=...&sort=...GET: /api/users/1

    //If you are using EF it could look like
    //filter and sort arguments could be added here as well
    public HttpResponseMessage Get(int? id)  
    {
       if(id.HasValue)
       {
           return Request.CreateResponse(
               HttpStatusCode.OK, 
               Context.Users.SingleOrDefault<Users>(u => u.Id == id));              
       }
    
       var users = Context.Users.Select(apply filter).OrderBy(apply sort).ToList();
       return Request.CreateResponse(HttpStatusCode.OK, users);   
    }
    
  4. 您可以查看OData - 它可以帮助您实施。

    1. 在不同的控制器之间传播这种逻辑会损害单一责任原则 - 您的用户控制器应该处理与用户相关的所有逻辑并且只处理这种逻辑
    2.   

      如果是这样,在这种情况下应该是POST还是GET?

      如果你想让你的API RESTful,你应该使用GET。 你应该知道,通过GET返回一组JSON对象可能容易受到JSON hijacking的攻击。这个漏洞利用的最简单的解决方案之一是允许通过POST获取JSON数组(还有其他解决方案)。

        

      我可能想要在单个用户的GET中返回比在搜索结果中更多的详细信息。如果同一个控制器确实为单个对象GET和GET返回一个集合返回不同的数据,它是否会使它不是RESTful?

      对于单个对象而不是集合,返回更多细节是完全正确的。它不会以任何方式影响API的RESTfulness。

      <强> COMMENT

      您写道:

        

      在指定ID时进行更新

      实际上并不完全正确:

      • PUT应该用于完全替换整个实体
      • 应使用PATCH执行部分更新。

答案 1 :(得分:2)

如果您希望将标准作为查询字符串参数传递给URI,则可以使用属性路由到WebApi来实现。我认为attribute-routing-in-web-api会对你有所帮助。

答案 2 :(得分:0)

是的,我会将过滤器参数作为查询字符串选项传递。应用程序的“restfulness”不依赖于控制器结构,因此您可以遵循最适合您应用程序的结构