在Visual Studio 2017中,当为.Net Core 2.1 Web API创建新的控制器时,并使用“使用实体框架添加Scaffold-具有操作的API控制器”向导,代码为PUT操作返回 NoContent(),为POST操作返回 CreatedAtAction()。
// POST: api/Items
[HttpPost]
public async Task<IActionResult> PostItem([FromBody] Item item)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
_context.Item.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction("GetItem", new { id = item.Id }, item);
}
// PUT: api/Items/5
[HttpPut("{id}")]
public async Task<IActionResult> PutItem([FromRoute] int id, [FromBody] Item item)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
if (id != item.Id)
return BadRequest();
_context.Entry(item).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ItemExists(id))
return NotFound();
else
throw;
}
return NoContent();
}
我完全同意POST操作的返回值。但是,关于返回空内容的NoContent()的PUT操作,这是RESTful API的“最佳实践”吗?我的意思是,我知道由于主体为空,它正在返回NoContent()状态代码,但是如果它返回Ok()来表示一切正常,那将没有任何意义吗?在接收到NoContent()状态代码时,该动作是否成功似乎有点模棱两可。还是返回NoContent()更正确,让使用中的应用知道它应该忽略主体,并假设由于未返回错误代码,所以一切正常?
只是想知道在这种情况下RESTful最佳实践是什么...
答案 0 :(得分:3)
不返回任何内容状态仍落在2xx状态码范围内,这都表示成功处理了请求。现在返回200只是选择问题,而不是在这种情况下最佳实践指示的条件。
引用Learn REST: A RESTful Tutorial - Using HTTP Methods for RESTful Services
PUT通常用于更新功能,将其PUT 请求主体包含新近更新的已知资源URI 原始资源的表示形式。
但是,在以下情况下,也可以使用PUT创建资源 资源ID由客户端而不是服务器选择。在 换句话说,如果PUT指向包含a值的URI 不存在的资源ID。同样,请求主体包含一个资源 表示。许多人感到这令人费解和困惑。 因此,在以下情况下,应谨慎使用这种创建方法: 全部。
或者,使用POST创建新资源并提供 主体表示中的客户端定义的ID(大概是URI) 不包含资源的ID(请参见下面的POST)。
成功更新后,返回200(如果未返回任何内容,则返回204 在体内)。如果使用PUT进行创建,则返回HTTP状态 成功创建201。响应中的一个物体是 可选-提供一个会消耗更多带宽。没必要 自创建以来,通过Location标头返回链接 客户端已经设置了资源ID。
PUT操作不安全,因为它会修改(或创建)状态 服务器,但它是幂等的。换句话说,如果您创建或 使用PUT更新资源,然后再次进行相同的调用, 资源仍然存在,并且仍然具有与之前相同的状态 第一次通话。
例如,如果在资源上调用PUT会增加一个计数器 在资源内,呼叫不再是幂等的。有时候 发生,可能足以证明该呼叫不是 幂等。但是,建议保持PUT请求幂等。 强烈建议对非幂等请求使用POST。