对于使用如下所示的端点更新单个实体(例如,文档)的标准REST PUT请求:
[Route("documents/{id}")]
public void Put(int id, [FromBody]Document document)
有一种明确定义的方法可以使用HTTP状态代码与客户端通信,使用HTTP 200状态进行成功更新,如果找不到具有指定Id的文档则使用HTTP 404,如果有,则使用HTTP 500更新记录等问题
我的问题是我们有一个可能具有极高使用率的RESTful API。出于性能原因,我们希望创建一个端点,该端点将接受多个文档实体,以便在单个PUT操作中进行更新:
[Route("documents")]
public void Put([FromBody]IEnumerable<Document> documents)
输入如下:
[
{"Id":1,"Name":"doc one","Author":"Fred"},
{"Id":2,"Name":"doc two","Author":"John"},
{"Id":3,"Name":"doc three","Author":"Mary"}
]
如果用户提交了10个文档,并且我只能成功更新其中的9个文件,而其余的文档因某些问题而失败,我想提交9个成功更新的文档,然后与用户进行更新通信成功了,哪些失败了。
我可以采取的一种方法是,如果任何提交的文档成功更新,则返回HTTP 200.在我返回到客户端的响应对象中,我可以包含那些成功的文档列表和文档列表失败了。对于每个失败的人,我可以列出原因,以及每个失败文档的HTTP状态代码。
但如果某些请求失败,我应该返回HTTP 200吗?此方法依靠客户端检查失败文档列表以查看是否存在问题。我担心的是用户会看到HTTP 200并假设一切正常。
另一个选项是,如果客户端提交了10个文档,并且我能够成功更新其中的9个文档并且其中一个文档失败,则返回失败的HTTP状态代码。例如,如果由于找不到指定的Id而导致失败,则返回HTTP 404,如果由于DB不可用而失败,则返回HTTP 500等。
这种方法也存在问题。例如,如果两个文档因不同原因而失败,应返回哪个HTTP状态代码?例如,为成功更新某些项目的请求返回HTTP 500状态是否有意义?
REST指南是否针对此批量更新问题提供了任何建议?是否有针对此问题的推荐方法?
答案 0 :(得分:1)
HTTP状态207 Multi Status
可用于处理批处理。
处理多个实体时,您的API可以返回包含响应列表的207
状态响应:
Id
可以用作密钥。RFC声明该消息是XML格式,但您可以将JSON与您自己的结构一起使用。 您可以查看处理batch processing的Jive API以查看示例。
给出输入
[
{"Id":1,"Name":"doc one","Author":"Fred"},
{"Id":2,"Name":"doc two","Author":"John"},
{"Id":3,"Name":"doc three","Author":"Mary"}
]
完全成功会返回207
http状态,该回复包含三个200
http状态:
[
{
"Id": 1,
"status": 200,
"data" : { data returned for a single processing }
},
{
"Id": 2,
"status": 200,
"data" : { data returned for a single processing }
},
{
"Id": 3,
"status": 200,
"data" : { data returned for a single processing }
}
]
如果ID为3的实体出现问题,例如缺少作者:
[
{"Id":1,"Name":"doc one","Author":"Fred"},
{"Id":2,"Name":"doc two","Author":"John"},
{"Id":3,"Name":"doc three"}
]
回复仍然是207
,但会为ID 1和2包含两个200
http状态,并为ID 3包含400
状态。
[
{
"Id": 1,
"status": 200,
"data" : { data returned for a single processing }
},
{
"Id": 2,
"status": 200,
"data" : { data returned for a single processing }
},
{
"Id": 3,
"status": 400,
"data" : { data returned for a single processing 400 error }
}
]