Surrogate key hacks


#1

If you want to set up creation and purging of content in your application, a healthy use of surrogate keys is recommended. Surrogate keys allow you to “tag” content in batches, and then purge the entire tag (and cluster of objects) all at once.

You can also create as many Surrogate Keys on an object as you need. We have a header size limit of 8kb, per Apache, but that’s 1024 characters (including spaces) you can work with. So, you shouldn’t hit many limits in the creation process.

For an example of something like this in action, take a look at this example from the Fastly-Rails gem:

In this example, set_surrogate_key_header concats table and record information to a Surrogate-Key: header response.

class BooksController < ApplicationController
  # include this before_filter in controller endpoints that you wish to edge cache
  before_filter :set_cache_control_headers, only: [:index, :show]
  # This can be used with any customer actions. Set these headers for GETs that you want to cache 
  # e.g. before_filter :set_cache_control_headers, only: [:index, :show, :my_custom_action]

  def index
    @books = Book.all
    set_surrogate_key_header @book.table_key
  end

  def show
    @book = Book.find(params[:id])
    set_surrogate_key_header @book.record_key
  end
end

In this purging example, @object.purge calls the single object purge API, and @object.purge_all calls the surrogate key purging api.

class BooksController < ApplicationController

  def create
    @book = Book.new(params)
    if @book.save
      @book.purge_all
      render @book
    end
  end

  def update
    @book = Book.find(params[:id])
    if @book.update(params)
      @book.purge
      render @book
    end
  end

  def delete
    @book = Book.find(params[:id])
    if @book.destroy
      @book.purge # purge the record
      @book.purge_all # purge the collection so the record is no longer there
    end
  end
end

There are lots of API wrappers available that can be used to implement a system like this: it’s not required to use Ruby or Rails to set something like this up.


#2

The 1024 byte limit has actually been raised to 16KB since this was posted. :slight_smile: