bwillis / versioncake

:cake: Version Cake is an unobtrusive way to version APIs in your Rails or Rack apps
655 stars 47 forks source link

Question regarding fragment caching #104

Open jcsanti opened 3 years ago

jcsanti commented 3 years ago

Hello,

I have a question regarding fragment caching in the context of an API that uses versioncake.

It seems natural that request_version is taken into account when computing hash digests but since I could not find confirmation in the docs, I've pondered whether I should be using request_version for each cache key computation.

As I'm not too familiar with ActionView or Version Cake internals, many thanks in advance for confirmation (or refutation!) of my assumption. πŸ™‚

––––––––––––––

_To illustrate my post, here is an example reflecting what's happening in my development logs. It that particular case, everything looks fine: for each "apiversion", different keys are set in Redis regardless of the level of nesting for partials that might exist in different versions.

Of course, feel free to take inspiration from it if you feel it could be a useful addition to the README. πŸ™‚

Main Template

json.id @shop.id
json.name @shop.name

json.product_categories do
  json.array! @product_categories do |category|
    json.cache! category do
      json.partial!("product_categories/product_category", product_category: category)
    end

    options = {
      expires_in: 10.minutes,
      key:        proc { |product| [product.cache_key] },
    }

    json.products do
      json.cache_collection!(category.products, options) do |product|
        # With "products/_product" being:
        #
        #   json.id product.id
        #   json.name product.name
        #
        #   json.properties do
        #     json.partial!("products/properties", properties: product.properties)
        #   end
        json.partial!("products/product", product: product)
      end
    end
  end
end

Files

# Main template
app/views/shops/show.json.v1.jbuilder

# Partials to cache
app/views/product_categories/_product_category.json.v1.jbuilder
app/views/products/_product.json.v1.jbuilder
app/views/products/_properties.json.v1.jbuilder

Redis logs on fragment writes/reads

1. additional v2 partial: _product_category.json.v2.jbuilder

call the endpoint with the Accept header "api_version=1"

1. writes
"set" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"

call the endpoint with the Accept header "api_version=2"

1. writes
"set" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"

2. additional v2 partial: _product.json.v2.jbuilder

call the endpoint with the Accept header "api_version=1"

1. writes
"set" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"

call the endpoint with the Accept header "api_version=2"

1. writes
"set" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"

3. additional v2 partial: _properties.json.v2.jbuilder

call the endpoint with the Accept header "api_version=1"

1. writes
"set" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:426bf4a8fc9234a5678bc084b0fec251/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:426bf4a8fc9234a5678bc084b0fec251/products/149804-20201215095631155288"

call the endpoint with the Accept header "api_version=2"

1. writes
"set" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"set" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"
2. reads (OK, same as writes)
"get" "jbuilder/views/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/product_categories/59-20210526151559895549"
"mget" "jbuilder/shops/show:4789c12d9fa9b6631a1948d1432ebf7f/products/149804-20201215095631155288"