发布项目时,获取项目而不是尝试将 ID 推回结果是不是是正确的形式?

Posted

技术标签:

【中文标题】发布项目时,获取项目而不是尝试将 ID 推回结果是不是是正确的形式?【英文标题】:When posting an item is it proper form to do a get on the item rather than try to push the ID back to the result?发布项目时,获取项目而不是尝试将 ID 推回结果是否是正确的形式? 【发布时间】:2020-07-17 16:34:04 【问题描述】:

我正在使用System.Net.Http.HTTPClient,并且在来自新 Xmanarin 项目的一些示例代码中,我有一个可以正常工作的方法。我的问题是:这是将对象返回给调用者的普遍接受的方法吗?

 public async Task<bool> AddItemAsync(Item item)
 
     if (item == null || !IsConnected)
         return false;

     var serializedItem = JsonConvert.SerializeObject(item);

     var response = await client.PostAsync($"api/item", new StringContent(serializedItem, Encoding.UTF8, "application/json"));

     /// dig out the URI and fetch it back to be restful...
     var json = await client.GetStringAsync(response.Headers.Location);
     item= await Task.Run(() => JsonConvert.DeserializeObject<Item>(json));
             
     return response.IsSuccessStatusCode;
  

【问题讨论】:

问题更多的是关于 REST 的 / 设计,而不是特定于 .NET Core x。代码可以有效地用 sh 和 cURL 编写。 @user2864740 这在 webapi 中仍然是一个好问题,因为我们必须了解代码的默认期望是什么。 我没有提出关于这是一个好/不好的问题的建议。原始标签是更新的主要内容。 【参考方案1】:

TL;DR:虽然看起来效率不高,但这种模式使客户端代码库非常简单,并允许服务器在应用业务逻辑/规则后以其他方式操作资源。

您是否应该在PUT/POST 之后立即重新获取资源?

这不限于 creation 事件,第一个点处理创建请求。

如果与您的帖子相关的服务器端处理有限或没有,那么在POST 之后立即调用同一资源的GET 将具有完全相同的内容,或者您​​可以轻松更新客户端,那么您只是通过等待相同的数据返回来减慢用户体验

如果可以从响应中确定资源的 uri(因此 Id/key),那么您可以简单地从响应中的 Location 或其他标头解析该值并更新客户端上的资源相应地。

某些 API 实际上会在响应正文中返回资源的内容,或者会有一个选项,您可以将其作为请求的标头发送以包含内容。如果您的 API 已在该响应中返回内容,并且该响应结构与您的应用所需的结构相匹配,那么再次立即调用 GET 没有任何价值。

查看您的 API 的首选 Header options,OData v4 prefer header 支持将在响应中返回资源的 return=representation

作为一般的客户端模式,在 createupdate 之后立即调用 GET 比尝试将 Id 和日期戳注入对象的代码更少,这意味着您隐含地支持 API 上的业务逻辑可能已经修改了您的资源(至少提供了一个 Id)的概念,因此对 API 本身的演变非常有弹性。

作为一般规则,在许多应用程序设计中创建操作很少发生,因此尽管在带宽方面效率较低,但保持代码清洁和可管理的成本是可以接受的。

你能一直使用response.Headers.Location来识别资源吗

通常使用 webapi,这是一个可靠的 REST 标准约定,但请继续阅读...

关于 Web API / REST,可以使用许多服务器端库和约定,从服务器的角度来看,它们会影响默认行为,通常他们会在对标准 CRUD 请求的响应中返回正确的 Location 标头

但这并不意味着开发人员使用了这些内置行为,或者没有覆盖它们!

这个讨论从 API 的角度突出了这个论点:REST response - should I put the URL of the new resource in the header, body, or both? 最终,API 开发人员可以影响每个单独请求的内容和标题,因此您确实需要查阅 API 文档或开发人员才能确定。

决定您确实需要刷新资源,如果您的 API url 约定意味着对 POST 的响应的 Location 始终是检索该资源的 uri ,那么请务必继续使用您拥有的代码,请注意并非所有 API,也并非所有请求都是相同的。

【讨论】:

以上是关于发布项目时,获取项目而不是尝试将 ID 推回结果是不是是正确的形式?的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 解析器,用于按名称而不是 ID 获取项目

React JS将项目推送到数组以获取列表

[我正在尝试删除一个项目,但是每次我单击按钮时,它都会返回错误“调度不是函数”]

单击表格视图行时如何推回视图?

杰克逊将单个项目反序列化为列表

替换而不是将项目添加到 Arraylist