繁体   English   中英

具有List属性的REST资源

[英]REST resource with a List property

我想要一些有关当前体系结构的反馈。

我有一个“人”资源,可通过GET和PUT请求访问:/ users / people / {key}。 资源产生并接受JSON格式的“ Person”对象。

这是GET /users/people/{key}可能返回的JSON示例:

{
 "age":29,
 "firstName":"Chiquita",
 "phoneNumbers":[
   {"key":"49fnfnsa0sas","number":"555-555-5555","deleted":false}
   {"key":"838943bdfb-f","number":"777-777-7777","deleted":false}
  ]
}

如您所见,“ Person”具有一些典型字段,例如“ firstName”和“ age”,以及更复杂的集合类型字段:“ phoneNumbers”。

我正在尝试设计资源,以便在更新资源时,客户端仅需要发回需要更新的字段。 例如,仅更新此人的名字:

PUT users/people/{key}

{
 "firstName":"New first name",
}

这样,来回传输的不必要信息要少很多(数量级的减少取决于资源的大小)

我的问题是,该如何处理列表属性(例如“ phoneNumbers”)。 我是否应该编写一些更复杂的代码来检查旧列表中的现有PhoneNumber按键,如果未引用它们则不触摸它们,如果有匹配的按键则更新它们,如果有带有新按键的PhoneNumber则添加它们? 还是我应该编写一些更简单的代码,将每个“ phoneNumbers”列表属性视为仅包含在“ PUT”请求正文中的另一个完全被覆盖的字段? 是否有一种标准的公认方法可以证明一种策略比另一种策略的问题少? 还是我会自行决定?

谢谢!

PUT的定义是它必须具有替换语义。 引入了PATCH动词以允许进行部分更新。 参见http://tools.ietf.org/html/rfc5789

至于如何做差异格式,确实没有对与错的方法。 这确实取决于您的上下文。

我认为每次更改某些内容时,让客户上载当前人员的所有信息将是最有意义的。 但是,在以下情况下,这可能不够充分:

  • 在典型情况下,每次更改都必须来回发送大量数据。
  • 多个人可以同时编辑同一个人。

如果您的人员对象很大,则可以考虑采用差异/补丁方法。 在发送新版本之前,请将其与旧版本进行比较。 如果单例字段(例如firstName)发生了变化,只需在JSON对象中列出它即可:

{
 "firstName":"New first name"
}

对于电话号码数组,请按键列出要删除的电话号码,然后像通常一样列出要添加的新电话号码。 像这样:

{
 "+phoneNumbers":[
  {"key":"123456789abc","number":"555-123-4567"}
 ],
 "-phoneNumbers":[
  "49fnfnsa0sas"
 ]
}

您也可以在Google中搜索“ json diff”,看看发现的任何结果是否有帮助。

就像我之前说过的那样,除非您有令人信服的理由进入如此复杂的深度,否则最好让客户端重新上传整个person对象来更新它。

正如其他人所说,PUT需要替换整个资源。 但是,作为架构师,您必须设计资源是什么。 也许“个人”记录中包含电话号码。 或者,也许更像是您在单独的表中使用电话号码建立关系数据库的方式。 在那种情况下,GET / users / people / {key}将仅获得名称和年龄,并且如果您想要一种获得电话号码和名称的方法,则可以定义查询参数。 GET / users / userphone / {key}将获取包含该人的电话号码(一个数组)的资源。

返回定义人员资源为其中包含电话号码,使用POST并没有错。 例如,POST的经典用法是将评论发布到网页或删除评论。 没有理由您无法定义POST操作来添加或删除电话号码。 POST是万事通,不管是好是坏。

(我注意到这里的按钮有充分的理由说是“发表您的答案”,而不是“发表您的答案”。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM