Hide and protect your AWS S3 endpoint (Rails+Nginx example)

It is very simple to use S3 as a storage for your static content in Rails application. Just add paperclip and aws-sdk gems. But what to do if you want to hide the direct links to S3 items, or even restrict access to some files by user’s roles and access rights? Here is a working example: Continue reading “Hide and protect your AWS S3 endpoint (Rails+Nginx example)”

Conditional GET for lists (nice trick)

Here is the nice trick to achieve Conditional GET request for lists (Index operation in classic REST terms). You know about this mechanism for single items (show operation): browser asks a resource for the first time, cache it’s last_modified value, and send “If-Modified-Since” header in the next request. A server checks database for resorce.update_at value, and responds “200 OK” with content as usual (if resource is newer), or responds with “304” without content if resource was not changed.

You can see an economy for computing resources, traffic, parsing and so on. But how to implement this technique for lists? Where is no “updated_at” attribute for the lists…

But don’t give up! Just get a newer resourse in the list, and use it’s “updated_at” attribute.

Here is an example for Ruby on Rails:
updated_at = models.max_by(&:updated_at).try(:updated_at) || Time.at(1)

The last part is a trick for empty lists. Easy!

Caveats: it will not work when you destroy a model from collection by real deleting from the database, because the newer “updated_at” value will not change or even becomes early. Browser will not get actual (changed) content. Use Paranoid gem (or mark it as something like ‘is_deleted’) instead, or switch to ETag.