Class: WCC::JsonAPI::ApiActionCaching::ApiActionCacheFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/wcc/jsonapi/concerns/api_action_caching.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ ApiActionCacheFilter

Returns a new instance of ApiActionCacheFilter.



53
54
55
# File 'lib/wcc/jsonapi/concerns/api_action_caching.rb', line 53

def initialize(options)
  @options = options
end

Instance Method Details

#around(controller) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/wcc/jsonapi/concerns/api_action_caching.rb', line 81

def around(controller)
  # cache path is the standardized request URL
  cache_path = self.cache_path(controller) ||
    controller.url_for(controller.params.permit!.merge(only_path: true))
  unless cache_version = self.cache_version(controller)
    raise StandardError, 'No cache_version specified'
  end

  # If we have run the action previously, our caching headers will be stored in the cache.
  # Use those cached headers to check our incoming request for freshness
  # (i.e. pretend that the action has already set ETag and Last-Modified then check freshness)
  status, headers = controller.cache_store.read(
    [:api_action_caching_headers, cache_path, cache_version],
  )
  controller.headers.merge!(headers) if headers

  if controller.request.fresh?(controller.response)
    # render 304 not modified
    return
  end

  # Cache permanent redirects
  if status == 301 && controller.headers['Location'].present?
    controller.response.status = status
    return
  end

  body = controller.read_fragment([cache_path, cache_version], nil)
  unless body && headers
    # The cache_version has been updated - rerun the action
    yield

    # Save the results of the action in the controller's Fragment Cache
    body = controller._save_fragment([cache_path, cache_version], nil)

    status, headers = controller.response.to_a
    controller.cache_store.write(
      [:api_action_caching_headers, cache_path, cache_version],
      [status, headers],
    )
  end

  # Assign the response body if we skipped running the action
  controller.response_body = body
  controller.response.status = status if status
end

#cache_path(controller) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/wcc/jsonapi/concerns/api_action_caching.rb', line 57

def cache_path(controller)
  cp = @options[:cache_path]
  case cp
  when Symbol
    controller.__send__(cp)
  when Proc
    controller.instance_exec(&cp)
  else
    cp
  end
end

#cache_version(controller) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/wcc/jsonapi/concerns/api_action_caching.rb', line 69

def cache_version(controller)
  version = @options[:cache_version]
  case version
  when Symbol
    controller.__send__(version)
  when Proc
    controller.instance_exec(&version)
  else
    raise ArgumentError, 'cache_version must be method name or proc'
  end
end