请帮我RESTful http缓存

时间:2015-07-02 08:38:06

标签: api rest http caching client-server

我正在开发一个移动应用程序,用于加载来自 REST服务器的数据。例如,此产品列表。产品存储在服务器上的数据库表中,具有以下结构:

| id | updatet_at          | name  | price |
|----|---------------------|-------|-------|
| 1  | 23.08.2015 06:00:00 | bread | 10    |
| 2  | 24.08.2015 12:00:00 | butter| 55    |
| 3  | 24.08.2015 12:00:00 | cheese| 180   |
| 4  | 24.08.2015 18:00:00 | sugar | 80    |

我的目标是了解标准缓存方案。现在我的缓存工作方式如下:

1)

GET /api/v1/products HTTP/1.1
Accept: application/json


HTTP/1.1 200 OK
Last-Modified: 24.08.2015 18:00:00
Content-Type: application/json

[
  { "id" : "1", "name" : "bread", "price" : 10 },
  { "id" : "2", "name" : "butter", "price" : 55 },
  { "id" : "3", "name" : "cheese", "price" : 180 },
  { "id" : "4", "name" : "sugar", "price" : 80 }
]

在服务器给我答案之后,我将数据缓存在本地数据库的同一个表中,唯一不同的是,我将updated_at每个元素== Last-Modified与服务器一起提供。所以我的本地数据库如下:

| id | updatet_at          | name  | price |
|----|---------------------|-------|-------|
| 1  | 24.08.2015 18:00:00 | bread | 10    |
| 2  | 24.08.2015 18:00:00 | butter| 55    |
| 3  | 24.08.2015 18:00:00 | cheese| 180   |
| 4  | 24.08.2015 18:00:00 | sugar | 80    |

然后我发送以下请求:

2)

GET /api/v1/products HTTP/1.1
Accept: application/json
If-Modified-Since: 24.08.2015 18:00:00


HTTP/1.1 304 Not Modified

[Empty body]

请求标头If-Modified-由于我替换了来自字段updated_at的最新日期,因为服务器数据未被更新或添加,所以响应从服务器304返回。让服务器添加一个条目,一个现有已更改:

| id | updatet_at          | name  | price |
|----|---------------------|-------|-------|
| 1  | 23.08.2015 06:00:00 | bread | 10    |
| 2  | 24.08.2015 12:00:00 | butter| 55    |
| 3  | 24.08.2015 12:00:00 | cheese| 180   |
| 4  | 26.08.2015 09:00:00 | sugar | 90    |
| 5  | 26.08.2015 08:00:00 | flour | 60    |

再次,我发送询问

3)

GET /api/v1/products HTTP/1.1
Accept: application/json
If-Modified-Since: 24.08.2015 18:00:00


HTTP/1.1 200 OK
Last-Modified: 26.08.2015 09:00:00
Content-Type: application/json

[
  { "id" : "4", "name" : "sugar", "price" : 90 },
  { "id" : "5", "name" : "flour", "price" : 60 }
]

收到此回复后,我根据答案更改id == 4的记录,并添加新条目。这两个记录我都从适当的服务器发出updated_at == Last-Modified响应。我对缓存的实现完全满意,直到我输入参数GET请求的选择。假设我清理了本地缓存并发送以下查询:

4)

GET /api/v1/products?min_price=60&max_price=100 HTTP/1.1
Accept: application/json


HTTP/1.1 200 OK
Last-Modified: 26.08.2015 09:00:00
Content-Type: application/json

[
  { "id" : "4", "name" : "sugar", "price" : 90 },
  { "id" : "5", "name" : "flour", "price" : 60 }
]

这里,在GET参数字符串中,我传递min_price = 60和max_price = 100。服务器根据我的请求,在现有元素中进行选择,并给出了2个适合的缓存方案,他用Last-Modified中所选元素中的最大值updated_at替换。我的客户端应用程序缓存数据。本地数据库如下:

| id | updatet_at          | name  | price |
|----|---------------------|-------|-------|
| 4  | 26.08.2015 09:00:00 | sugar | 90    |
| 5  | 26.08.2015 09:00:00 | flour | 60    |

现在,当我发送所有产品的请求时:

5)

GET /api/v1/products HTTP/1.1
Accept: application/json
If-Modified-Since: 26.08.2015 09:00:00


HTTP/1.1 304 Not Modified

[Empty body]

事实证明,由于我已经提供了最大updated_at这一事实,我不能变老(使用updated_at}个产品,因此我的缓存计划失败了。提示如何对动态数据使用标准HTTP缓存?

1 个答案:

答案 0 :(得分:0)

如果您要请求个人资源,则可以使用单独的FragmentManager值。但是如果您想使用updated_at请求整个集合,则需要单独跟踪上次请求整个集合的时间。否则,您将遇到您正在看到的问题,因为个别记录可能会独立于整个集合进行更新。

假装您使用If-Modified-Since而不是上次修改日期。您不会发送ETag个人记录,并期望收回正确的收集结果,不是吗?

另一个合理的选择是在没有ETag的情况下请求集合,然后执行单独的GET来检索资源,为每个单独的资源发送ETag。这种方法对你来说可能太吵了也可能没有。