REST问题:PUT一个表示,获得一个不同的表示?

时间:2009-12-22 03:38:44

标签: http rest uri content-type mime

问题的简短版本:
特定URI的“GET”是否需要与“PUT”匹配到该URI?

我想不是。原因如下:

鉴于资源是客户理论上不可知的抽象事物,当我们进行PUT时,我们必须只发送一个表示。基于对RFC2616的梳理,对于具有许多(可能是无限的?)表示的资源来说,它似乎没有完全明确,但这是我的想法;如果您同意,请告诉我:

我的期望是,如果我将表示赋予资源,那么该URI上资源的所有其他表示应该保持一致(可能更新)。换句话说,您告诉资源“使用此表示来重新定义自己”。

因此,我应该能够做到这一点:

  

PUT / resources / foo / myvacation
  内容类型:image / jpg
  ......

然后跟进:

  

GET / resources / foo / myvacation
  接受:image / png
  ...

以不同的格式获取myvacation的更新版本(假设服务器知道如何操作)。从中推断出,这个复合原子“图像+元数据”PUT也应该是合法的:

  

PUT / resources / foo / myvacation
  内容类型:multipart / form-data

     

内容处理:表单数据; NAME = “文件”
  内容类型:image / jpg
  [..]
  内容处理:表格数据; NAME = “IPTC”
  内容类型:application / iptc
  [..]
  内容处理:表格数据; NAME = “EXIF”
  内容类型:application / exif
  [..]

然后,因为服务器端内容协商(RFC2616第12.1节)可以基于任何事情进行,我们可以默认为“文档”内容:

  

GET / resources / foo / myvacation
  内容类型:image / jpg
  [..]

或者如果你像我一样认为RFC 2396第3.4节“查询组件是由资源解释的一串信息。”意味着带有查询字符串的URI引用与没有查询字符串的URI相同的资源(并且只是将application / x-form-urlencoded数据发送到资源是同构的),那么这也应该是合法的:

  

GET / resources / foo / myvacation?content = exif
  内容类型:application / exif
  [..]

PUT的描述说:

PUT方法请求将所包含的实体存储在提供的Request-URI下。

对我来说,这是相当反REST的,除非你以非常自由的方式阅读它。我的解释是“PUT方法根据所包含实体的表示请求在提供的Request-URI上创建或更新资源。”

稍后,我们得到:

POST和PUT请求之间的根本区别体现在Request-URI的不同含义上。 POST请求中的URI标识将处理所包含实体的资源。该资源可能是数据接受过程,某些其他协议的网关或接受注释的单独实体。相反,PUT请求中的URI标识请求附带的实体 - 用户代理知道URI的用途,服务器不得尝试将请求应用于其他资源。

我们需要同样地创造性地阅读这一点,但这里的关键点是“知道什么是URI”和“应用请求”。

所以,对我来说,GET在给定URI处返回的表示不一定必须与给定URI的PUT相同,只需要保持一致。

是真还是假?

4 个答案:

答案 0 :(得分:5)

基于内容协商可以从同一个URI返回不同表示的事实,我很确定你的PUT不必与你检索的内容相同。

答案 1 :(得分:3)

您的假设是正确的。 GET不一定必须返回与您PUT相同的表示,但它必须是相同的资源

我目前正在开发一个Web应用程序,它将返回任何资源,如XHTML,JSON或自定义XML方言,具体取决于您在内容协商标头中要求的内容。因此,浏览器默认会看到HTML。其他HTTP客户端(包括XMLHttpRequest)可以获取JSON,依此类推。它们都是同一URI上相同资源的表示。

同样,我们的应用程序将接受任何支持格式的PUT或POST(取决于所讨论的特定资源或集合的语义。)

答案 2 :(得分:2)

我同意其他答案,你PUT的资源不需要与你以后获取的资源相同。我想在这个领域为这个问题增加一些经验。

依赖内容协商时,您需要非常小心。这是非常棘手的,如果你没有做到正确导致令人讨厌的用户问题。让我们根据图像做一个例子......

如果Alice以原始格式输出图像,那么Bob可以将图像作为jpeg(通过服务器端raw-> jpeg变换)获取,并且Alice可以以原始格式获取图像;没问题。但是,如果Bob PUTs是一个jpeg,那么就没有办法回到Alice的原始格式。在度假照片的情况下,缺乏对称变换可能不是什么大问题,但在医学图像中它将是。

缺乏对称变换的另一个领域是在一个表示中,其中一个具有模式而另一个没有。在这种情况下,在服务器端,您最终会制定如何在它们之间进行转换的约定。但是,当您处理的模式随着时间的推移而发生变化并且不受您控制时,您会遇到大问题。每次架构更改时,您都必须更新新架构形状的所有转换,同时仍使用旧架构支持资源。除了一些有限的情况外,内容协商很快就会变得比它的价值更麻烦。可以管理的一个方面是,您是否完全控制资源表示及其底层架构。另一个领域是资源格式是标准,并且可以在不同格式之间进行对称转换。

答案 3 :(得分:1)

如果你正在改变那么你PUT不是你GET的那个是有意义的,所以我不明白为什么它是一个问题。

但是,如果您PUT某个用户拥有某些信息,那么当您使用GET时,它应该检索该人,就像我第四张假期照片时,我打电话{{ 1}}我希望这张照片,但它可以通过转换为不同的格式进行转换,或者进行其他一些转换,但是,如果我得到第5张照片,那么这就是问题。