我正在使用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?
答案 0 :(得分:2)
对于上面的第一个网址,我还需要发送各种过滤器/搜索条件。此条件是否仅作为查询字符串参数传递?
使用查询字符串指定过滤器/搜索参数绝对有意义。
我是否应该使用完全不同的控制器来进行此操作"搜索"功能?例如。 UserSearchController?
你不应该这样做。我在这里看到了几个原因:
GET: /api/users
您可以在一种方法中轻松实施GET: /api/users
,GET: /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);
}
您可以查看OData - 它可以帮助您实施。
如果是这样,在这种情况下应该是POST还是GET?
如果你想让你的API RESTful,你应该使用GET。 但你应该知道,通过GET返回一组JSON对象可能容易受到JSON hijacking的攻击。这个漏洞利用的最简单的解决方案之一是允许通过POST获取JSON数组(还有其他解决方案)。
我可能想要在单个用户的GET中返回比在搜索结果中更多的详细信息。如果同一个控制器确实为单个对象GET和GET返回一个集合返回不同的数据,它是否会使它不是RESTful?
对于单个对象而不是集合,返回更多细节是完全正确的。它不会以任何方式影响API的RESTfulness。
<强> COMMENT 强>
您写道:
在指定ID时进行更新
实际上并不完全正确:
答案 1 :(得分:2)
如果您希望将标准作为查询字符串参数传递给URI,则可以使用属性路由到WebApi来实现。我认为attribute-routing-in-web-api会对你有所帮助。
答案 2 :(得分:0)
是的,我会将过滤器参数作为查询字符串选项传递。应用程序的“restfulness”不依赖于控制器结构,因此您可以遵循最适合您应用程序的结构