1

我想使用 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 方式是什么?

经过一番研究,我最后的看法是:

  • 让 Product(123) 按原样工作
  • 如果 $filter=sku eq 123 / id eq 123 响应 HTTP 302 和 Location 标头指向 Product(123)。
  • 如果 Product(123)?$filter=sku eq 123 以 400(错误请求)响应,因为它很愚蠢。或者可能使用 302 重定向到 Product(123)..

但是最后一个案例怎么办?

4

1 回答 1

2

Product(123) -> 您应该在响应负载中返回单个实体

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

Product?$filter=sku eq 123 -> Product 标识一个实体集,因此应该返回一个实体集合(AKA 提要)。即使您的特定查询碰巧识别了单个实体,其中包含单个实体的提要也是必需的响应。

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

你说你想保持一个实体有一个 URL 的规则。在 OData 中,一个 URL 标识一个实体,尽管多个 URL 可以为您提供有关它的相同信息。所以,我认为你没问题。标识资源的一个 URL 称为规范 URL。Product(123) 是一个规范的 URL。例如,在 JSON 有效负载中,odata.id 将给出实体的规范 URL。

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

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

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

于 2013-07-15T22:57:22.657 回答