处理HTTP缓存OData查询的正确方法是什么?

时间:2013-07-15 11:22:22

标签: rest odata http-get http-caching

我想使用OData并从HTTP缓存中获得一些好处。我已经确定了规则“一个实体有一个URI”。有多种方法可以对一个实体执行查询,比如说SKU = 123的产品(这是PK):

/MyService.svc/Product(123)

/MyService.svc/Product?$filter=sku eq 123

甚至

/MyService.svc/Product(123)?$filter=sku eq 123

如何查询此产品最晦涩的方式是通过标题:

/MyService.svc/Product?$filter=title eq 'Some handy product'

(假设此查询只返回一个实体 - 产品123)

我的问题是: OData方式最多如何回应此类查询?

经过一番研究,我的最后一点意见是:

  • 让产品(123)按原样工作
  • 如果是$ filter = sku eq 123 / id eq 123使用HTTP 302和Location标题响应Product(123)。
  • 在产品(123)的情况下?$ filter = sku eq 123用400响应(Bad Request),因为它很傻。或者可能使用302重定向到Product(123)..

但是如何处理最后一个案例?

1 个答案:

答案 0 :(得分:2)

产品(123) - >您应该在响应有效负载中返回单个实体

产品(123)?$ filter = sku eq 123 - >这实际上没有意义 - 过滤器应该应用于实体集合,而Product(123)标识单个实体(总是)。今天许多OData服务由于行为或早期服务器堆栈而忽略了这一点,但由于查询选项不适用,因此可接受400。

产品?$ filter = sku eq 123 - >产品标识实体集,因此应返回实体集合(AKA订阅源)。即使您的特定查询恰好识别单个实体,但其中包含单个实体的Feed也是必需的响应。

产品?$ filter = title eq'一些方便的产品' - >就预期的响应而言,这与sku eq 123相同。即使它可能标识单个资源,但这并不会改变实体集必须仍包含作为响应的提要的事实。

您说过要保留一个实体有一个URL的规则。在OData中,一个URL标识一个实体,但多个URL可以为您提供相同的信息。所以,我认为你没问题。标识资源的一个URL称为规范URL。产品(123)是规范URL。例如,在JSON有效载荷中,odata.id将给出实体的规范URL。

那么SEEM引用同一个实体的其他查询呢?在您的有效过滤器示例(第3和第4个)中,您的路径标识了我在上面指出的COLLECTION。集合恰好只包含一个实体这一事实无关紧要。 IDENTIFIES资源的路径仍然是Product(123)。其他URL可以提供有关该实体的信息而无需“识别”它。所以我不认为你以任何方式破坏了你的陈述。

回答问题的3xx部分:您总是可以自由地回复具有某种重定向的请求 - 这是HTTP的一部分,而OData不会改变它。但是,重定向到与原始请求形状不同的内容将是一个糟糕的服务器行为。例如,Product(123)?$ filter =标识产品实体集合的任何内容。在我看来,重定向到产品(123)将是一个坏主意,因为它识别单个实体。你写出来的反应看起来会有所不同!如果任何现有的OData客户端能够处理它,我会感到惊讶,我也不希望新的客户端处理它。

这对HTTP缓存意味着什么?嗯,坦率地说,至少在给出的情景中,我认为你不应该做任何特别的事情。