Grape Api Use Etag

基于 Grape 开发 APP API 后端,已经有一年之久了。在项目里引入 Grape 有几点考虑:RESTful APIs;版本管理;接口参数管理;路由管理等。 一年前的一篇博客对 Grape 的使用和设计,有更详细的介绍 API Design And Code Implementation

本篇记录了在 Grape API 的基础上,实现了 HTTP 协议 Etag 的机制。

Etag 介绍

Etag(Entity Tag)是 Web 服务器和浏览器用于确认缓存组件的有效性的一种机制。
服务器在检测缓存的组件是否和原始服务器上的组件匹配时,有两种方式:
1. 比较最新修改日期
2. 比较实体标签

Grape API 实现 Etag 策略

基于 Grape 实现 HTTP Etag 比较实体标签的机制,处理逻辑如下:
1. 获取 Get 接口(资源列表或者详情)的数据,记为 data
2. 为 data 生成 cache key,并将 cache key 做 MD5 计算,得到 Etag
3. 将 Etag 添加到 HTTP Header,返回给客户端
4. 从客户端的请求中获取 Etag,比较 Etag 是否相等
5. 相等则直接返回 304 Not Modified,否则,重新返回数据

源代码

部分代码如下,完整源代码请参考这里 Github grape_demo

    module GrapeCache
        extend ActiveSupport::Concern

        def compare_etag(etag)
          etag_key = ActiveSupport::Cache.expand_cache_key(etag)
          etag_value = Digest::MD5.hexdigest(etag_key)

          error!("Not Modified", 304) if request.headers["If-None-Match"] == etag_value

          header "ETag", %("#{etag_value}")
        end
    end

2014-10-06

rocket-wing