代码之家  ›  专栏  ›  技术社区  ›  Chris Dutrow

具有列表属性的REST资源

  •  0
  • Chris Dutrow  · 技术社区  · 16 年前

    我想要一些关于我目前架构的反馈。

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

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

    {
     "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",
    }
    

    谢谢!

    3 回复  |  直到 16 年前
        1
  •  1
  •   Joey Adams    16 年前

    我在想,最有意义的做法是每次发生变化时,让客户上传当前用户的所有信息。但是,如果:

    • 多个人可以同时编辑同一个人。

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

    {
     "firstName":"New first name"
    }
    

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

    你也可以在谷歌上搜索“json diff”,看看你找到的结果是否有用。

    正如我之前所说的,除非你有一个令人信服的理由去达到这种复杂程度,否则最好让客户端重新上传整个person对象来更新它。

        2
  •  2
  •   Darrel Miller    16 年前

    PUT的定义是必须有替换语义。引入PATCH动词是为了允许进行部分更新。看到了吗 http://tools.ietf.org/html/rfc5789

        3
  •  1
  •   Mark Lutton    16 年前

    正如其他人所说,PUT需要替换整个资源。但是,作为架构师,您需要设计资源是什么。也许个人记录里有电话号码。或者更像是在一个单独的表中设置电话号码的关系数据库。在这种情况下,GET/users/people/{key}将只获取姓名和年龄,如果希望通过某种方式获取电话号码和姓名,则可以定义查询参数。GET/users/userphone/{key}将获取包含此人电话号码的资源,一个数组。

    回到将Person资源定义为包含其中的电话号码,使用POST没有什么错。例如,POST的经典用法是将评论发布到网页或删除评论。没有理由不能定义添加或删除电话号码的POST操作。不管是好是坏,POST都是随遇而安的方法。

    (我注意到这里的按钮是“发布你的答案”,而不是“放置你的答案”,这是有充分理由的。)