使用Post以RESTfully方式更新值

使用Post以RESTfully方式更新值,rest,Rest,我是个新手,所以如果这是个愚蠢的问题,请原谅我 所以,我有一个客户资源。顾客有很多信用。所以,我想获取客户信用的URL应该是 客户/21/学分 (其中21是客户ID) 现在,如果我没有全部的学分,我如何增加学分?例如,一个客户有10个积分,我想加5个。据我所知,如果我使用post,我会这样做: 客户/21/信用额?金额=15(这是否正确?) 但是,如果我只是想增加现有的学分,该怎么办?也就是说,我想发送5个积分,并说将它们添加到客户当前拥有的任何内容中?我是否定义了一种幻象资源,如addedCr

我是个新手,所以如果这是个愚蠢的问题,请原谅我

所以,我有一个客户资源。顾客有很多信用。所以,我想获取客户信用的URL应该是

客户/21/学分

(其中21是客户ID)

现在,如果我没有全部的学分,我如何增加学分?例如,一个客户有10个积分,我想加5个。据我所知,如果我使用post,我会这样做:

客户/21/信用额?金额=15(这是否正确?)

但是,如果我只是想增加现有的学分,该怎么办?也就是说,我想发送5个积分,并说将它们添加到客户当前拥有的任何内容中?我是否定义了一种幻象资源,如addedCredits

客户/21/新增信用?金额=5


然后在幕后,我只做credits+=5?

对于初学者来说,使用URI查询参数应该是一种“坏味道”。其次,您需要了解如何定义一些mime类型,您的客户机和服务器可以使用这些类型进行对话,例如,您的信用卡示例:

如果我做一个GET-on customer/21/credits,我可能会得到这样一个文档:

内容类型:application/vnd.creditstore+xml

<credits>
   <user>21</user>
   <credits>10</credits>
   <a href="/customer/21/credits/add" rel="add">Add credits to this account</a>
</credits>

21
10
这会告诉了解您的vocab的客户,如果他们想向该用户添加信用,他们需要在该链接上发布一些内容。这是HATEOAS(上帝啊,我讨厌这个首字母缩写词,我甚至可能把它拼错了)


现在,这一切都完全超出了我的想象,我可能已经扼杀了这个XML示例,但它应该让您朝着正确的方向思考。

最终实现取决于您。虽然URI查询参数通常不受欢迎,但这并不意味着您不能使用它们。就我个人而言,我会将post URI设置为:

客户/21/学分/add/5

但没有什么能说明你不能做你所拥有的或:

客户/21/学分/增值=5


您需要定义如何处理系统中的“积分”;您是否打算将它们定义为资源或客户资源的属性很重要

在下面的示例中,我将使用XML表示资源/实体。这可能适用于您,但您需要在请求和响应中使用一致的方式表示资源-这将帮助您避免使用查询参数(例如?foo=bar)来定义属于请求主体的数据

表示信用的两种方式:

  • 如果“信用”是“客户”的属性:

    或者您可以将以下内容发布到
    /customer/21/credits
    (假设URI是应用于客户的所有
    的列表):

    
    2009-10-15 15:00:00
    5.
    
    这将在现有列表中“附加”一个新的
    。而且还消除了在实体中提供
    的需要,因为它已经存在于URI中


  • 我会使用相同的URL

    POST to
    customer/21/credits
    ,并将名为extraCredit的POST变量设置为5。POST应该用于(或创建下属资源)。没有理由需要一个新的URL

    如果个人信用是您系统中值得拥有自己URL的资源,则发布到
    customer/21/credits
    的响应URL应包括新信用资源的URL,例如
    customer/21/credit/12

    您可以定义一个XML表示,以将其发送到<代码>客户/ 21 /学分< /代码>,但在这个简单的例子中,我不认为它值得。REST有效负载不必是XML

    customer/21/addedCredits?amount=5这样的URL对我来说没有意义,因为它不能真正识别资源。如果有人发出GET to
    customer/21/addedCredits?amount=5
    你会给他们什么回报


    有一件事你绝对不应该做,那就是当有人收到像
    customer/21/addedCredits?amount=5这样的URL时,改变客户资源的状态。既然你的问题的标题承认你需要使用你的帖子,你可能会意识到这一点。GET应该是安全的,这意味着发出GET不应该改变资源的状态。

    据我所知,这不是resful,因为URL中有动词,这两个URL都不能识别资源。正如NG所说,它们包含动词。在REST中,动词应该在HTTP方法中捕获,但我认为resful URL中不应该包含动词。Add是动词。我认为你应该定义一个新的资源来更新-因此我的想法是addedCredits。事实上,这不是一个坏主意,我同样在2秒钟内完成了。我看到的唯一问题是,POST是为了创建一个新的资源,而向现有帐户添加5个学分对我来说并不像POST操作。显然,使用URI查询参数告诉它要添加多少是错误的。向../credits URI发出PUT可能是一个可接受的解决方案。使用像上面那样的自定义XML文档告诉服务器要添加多少信用。POST并不意味着创建新资源。它应该附加到现有资源上。如果“信用”是系统中的名词/资源/项目,则添加5个信用将是一个后期操作。如果不是,那么你可能不能发布任何东西,因为你没有实体发布。从这个问题我们知道信用是一种资源,所以我们可以发布到它。什么是“发布变量”?我认为你关于“发布更新现有资源”的陈述是不正确的。POST用于创建,PUT用于创建/更新。当然,这些方法的实际实现取决于对服务器进行编码的人。RE:我上面的评论——事实上,经过更多的研究,我看到不同的地方对帖子进行了描述,并在创建和更新方面采取了不同的做法。耶,不一致@ctford-我认为这取决于资源
    <customer id="21">
      <balance>10</balance><!-- aka credit -->
    </customer>
    
    <credit>
      <dateApplied>2009-10-15 15:00:00</dateApplied>
      <customer href="/customer/21"/>
      <amount>5</amount>
    </credit>
    
    <credit>
      <dateApplied>2009-10-15 15:00:00</dateApplied>
      <amount>5</amount>
    </credit>