使用 Web API 执行对象副本时要使用的 RESTFull HTTP 方法

Bla*_*ell 3 c# asp.net asp.net-web-api asp.net-web-api2

我有一个 ProductsController,我想创建一个复制产品的操作方法。它只需要一个参数,它是一个 Id,它促使我想要使用一个简单的 GET 请求。不过,有些东西告诉我 GET 在这里没有意义。我真的使用 POST 并将单个 Id 传递给此方法吗?

这是我想出的:

// COPY: api/products/{id}/copy
[HttpPost("{id}/copy")]
public void Copy(int id)
{
    _productManager.Copy(sourceProductId: id);
}
Run Code Online (Sandbox Code Playgroud)

Fed*_*uma 6

我基本上会使用以下方法之一来处理这种情况:


1. COPY

不要按WebDAV规范,只是使用COPY的HTTP方法。我相信,这是以 RESTful 方式克隆/复制资源在语义上最正确的方法。请注意,REST 不限制您仅使用默认动词:

[AcceptVerbs("COPY")]
[Route("{id}")]
public void Copy(int id)
{
    _productManager.Copy(sourceProductId: id);
}
Run Code Online (Sandbox Code Playgroud)

2. POST

继续使用用于创建新资源的相同方法(因为毕竟您正在创建新资源),但使用可选的查询字符串参数来确定您是否正在复制现有资源。
然后,您将通过发送触发复制操作POST一个空的身体要求为URI类似于以下之一:http://myhost/api/products?sourceId=1。这是一个代码示例:

[HttpPost]
[Route("")]
public void CreateOrCopy([FromBody] ProductDTO dto, [FromUri] int? sourceId = null)
{
    if(dto == null && sourceId.HasValue)
        _productManager.Copy(sourceProductId: id); // copy behavior
    else
        // normal behavior
}
Run Code Online (Sandbox Code Playgroud)

我认为从客户端的角度来看,这两种方法都非常有用,而不会破坏 REST 约束或语义含义(绝对避免GET出于此类目的使用 )。

  • 将 /copy 附加到 URI 根本不安全。我建议您使用已使用的相同 POST 方法,并在查询字符串或请求正文中检查这些参数。 (2认同)