附加到资源';restfuly属性

附加到资源';restfuly属性,rest,Rest,这是一个后续行动 如何使用REST简单地附加到资源的属性。假设我有customer.balance,balance是一个int。假设我只想告诉服务器在当前余额的基础上附加5。我能平静地做这件事吗?如果是,怎么做 请记住,客户不知道客户的现有余额,因此不能 获得客户 客户余额+=5 邮政客户 (上面也会有并发性问题。)要以休息的方式考虑这一点,您需要将操作本身视为一种资源。例如,如果这是银行业务,并且您希望更新帐户上的余额,那么您将创建一个存款资源,然后添加其中的一个。这样做的结果是更新客户的余额

这是一个后续行动

如何使用REST简单地附加到资源的属性。假设我有customer.balance,balance是一个int。假设我只想告诉服务器在当前余额的基础上附加5。我能平静地做这件事吗?如果是,怎么做

请记住,客户不知道客户的现有余额,因此不能

  • 获得客户
  • 客户余额+=5
  • 邮政客户

  • (上面也会有并发性问题。)

    要以休息的方式考虑这一点,您需要将操作本身视为一种资源。例如,如果这是银行业务,并且您希望更新帐户上的余额,那么您将创建一个存款资源,然后添加其中的一个。这样做的结果是更新客户的余额

    这也有助于处理并发问题,因为您将提交+5操作,而不需要事先了解客户的余额。而且,您还可以回忆起该资源(例如,对于ID为51的存款,使用存款/51),并查看有关该资源的其他详细信息(即存款原因、存款日期等)

    编辑:意识到使用存款id 5实际上会混淆问题,因此将其更改为51。

    简单,有点难看: 这是我的一个更简单的变体

    我认为,如果您执行以下操作,您仍然处于REST的约束范围内。然而,我也很好奇其他人对这种情况的看法,所以我希望听到其他人的意见

    您的URI将是:

    /customer/21/credits
    
    您将信用资源(可能是
    5
    )发布到URI,然后服务器可以获取客户的余额,并
    +=
    将其与提供的值一起使用。此外,您可以支持负信用(例如
    -10

    请注意,
    /customer/21/credits
    不必支持所有方法。只有支柱是完全可以接受的

    然而,如果信用卡不是系统中真正的资源,这就有点奇怪了。报告说:

    如果已在源服务器上创建资源,则响应应为201(已创建),并包含描述请求状态并引用新资源的实体以及位置标头

    从技术上讲,您不是在这里创建资源,而是附加到客户的余额(实际上是系统中所有以前信用的总和)。由于您没有保留信用(大概是这样),因此无法返回对新“创建”信用资源的引用。您可能会返回客户的余额,或者
    本身,但这对客户来说有点不直观。这就是为什么我认为将每个学分作为系统中的一个新资源更容易处理的原因(见下文)

    我的首选解决方案: 这是根据我在你的另一个问题中的回答改编的。在这里,我将试着从客户机/服务器正在做什么的角度来探讨它:

    • 客户:

    • 建立新的信贷资源:

      <credit>
        <amount>5</amount>
      </credit>
      
    这为您提供了以下优势:

    • 以后可以通过id访问信用卡(使用GET
      /customer/21/Credits/[id]
    • 您有完整的信用历史审计记录
    • 如果您支持,客户端可以按id更新或删除信用(使用PUT或DELETE)
    • 如果您支持,客户端可以检索信用的有序列表;e、 g.
      GET/customer/21/credits
      可能返回:

      <credits href="/customer/21/credits">
         <credit href="/customer/21/credits/credit-id-7382134">
           <amount>13</amount>
           ...
         </credit>
         <credit href="/customer/21/credits/credit-id-134u482">
           ...
         </credit>
         ...
      </credits>
      
      
      13
      ...
      ...
      ...
      
    • 有道理,因为客户的余额实际上是应用于该客户的所有信用的最终结果

    嗯,除了@Rob Hruska的解决方案,还有其他选择

    基本思想是一样的:将每个贷记/借记操作视为一个独立的事务。然而,我曾经使用过一个后端,它支持在json中存储无模式的数据,因此我最终将API定义为带有动态字段名的PUT。大概是这样的:

    PUT /customer/21
    
    {"transaction_yyyymmddHHMMSS": 5}
    
    我知道这在“贷记/借记”上下文中是不合适的,因为一个活跃账户可能有不断增长的交易记录。但在我的环境中,我使用这样的策略来存储有限的数据(实际上,我在一次驾车旅行中存储了不同批次的GPS路径点)

    缺点:这种api风格严重依赖于后端行为的无模式特性

    优点:至少从语义的角度来看,我的方法是完全RESTful的


    相比之下,@Rob Hruska的“简单,稍微难看”解决方案1在“201 Created”响应中没有要返回的有效位置头,这不是常见的RESTful行为。(或者,我们可以让@Rob Hruska的解决方案1也返回一个虚拟位置标题,它指向“410消失”或“404未找到”页面。这是否更安静?欢迎评论!)

    因此我可以创建一个示例:customer/21/debits customer/21/credits,每个示例都有一个借方和贷方资源集合?现在,在引擎盖下,我只想+=贷方金额-=借方关于客户的余额。这意味着无法获得客户/21/credit/5。休息时间可以吗?根据你的回答,似乎不是。要创建一个新的借方,我会发布到customer/21/debits/new,并将5作为金额包含在帖子中。如果我想得到id为5的借记卡,我会得到customer/21/debit/5,当然,创建新资源时不应该将其放在POST上。我很高兴你问了这个问题,尽管我有点失望,因为它没有太多活动。我想看看经验丰富的人对这个话题有什么看法。你的方法对我来说似乎是最合乎逻辑的。@Darrel-谢谢。我真的很想知道你有没有别的选择。你的标签表明你对REST很感兴趣,而且你可能比我更有经验。有什么建议吗
    PUT /customer/21
    
    {"transaction_yyyymmddHHMMSS": 5}