【问题标题】:Using POST or GET for a WebAPI Action method that returns a list, but requires params将 POST 或 GET 用于返回列表但需要参数的 WebAPI 操作方法
【发布时间】:2016-09-08 18:30:18
【问题描述】:

目前我在每个控制器中都有以下标准函数来处理基本的 CRUD 操作:

GET /api/todo           Get all to-do items
GET /api/todo/{id}      Get an item by ID
POST /api/todo          Add a new item
PUT /api/todo/{id}      Update an existing item
DELETE /api/todo/{id}   Delete an item

然而,我意识到我实际上需要传递多个参数来获取在数据库级别过滤的待办事项列表,而不是检索所有项目并使用 linq。

例如,我决定这样做:
在我的控制器中:

// POST: api/todo
[HttpPost]
public IList<TodoItem> Get([FromBody]GetTodoItemsRequest request)
{
    return _todoItemManager.GetTodoItems(request.Name, request.CategoryId);
}

如您所见,我创建了一个名为 GetTodoItemsRequest 的新模型,该模型将为我的每个参数提供一个属性。在这种情况下:名称、CategoryId。

我认为在处理多个参数并检索列表时,最好执行 POST 并专门为其创建模型。而不是使用 GET 并在 url 中传递各种信息。

执行上述操作似乎有点奇怪...... msot 会认为这是一个完美的解决方案,还是我在 WebAPI 世界中缺少什么?

【问题讨论】:

标签: c# asp.net asp.net-web-api asp.net-web-api2 asp.net-core


【解决方案1】:

我认为使用POST 方法进行简单的读取操作在语义上是不正确的,即使您需要一个复杂的模型。您正在对名为 todo 的资源进行纯查询,这实际上应该是 GET 操作,原因有很多:

  1. 应该可缓存POST 请求本质上是不可缓存的,缓存是 RESTful 服务中的一个重要约束。
  2. 它应该在语义上表明调用不会引发副作用GET 请求必须是幂等安全,相反,POST 操作表示某种数据操作。您的操作(过滤)既是幂等的又是安全的,因此它应该由 GET 请求自发表示。
  3. ? 字符之后的 URI 部分称为查询字符串,原因是:它表示进一步指定请求的范围的参数。那么,过滤结果不只是这种方法的一个例子吗?

除此之外,在我看来,如果 NameCategoryId 是您的查询所需的参数,则您的过滤操作可以由另一个 URI 更好地表示,其中 NameCategoryId 被转换为路由参数:

http://yourhost.com/api/users/{name}/categories/{categoryId}/todos

假设您的name 参数(可能是用户名?)和categories 之间存在关系。

相反,如果您的参数是完全可选的,那么最好将它们保留为查询字符串参数:

http://yourhost.com/api/todos?name=nameValue&categoryId=categoryIdValue

附注:
如果您的资源代表一组项目,您应该真正使用复数:例如api/todo 将返回一个待办事项数组,因此您应该将其重命名为 api/todos

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    相关资源
    最近更新 更多