implement request caching

This is a preliminary implementation, meaning that it is still not heavily
tested. One current drawback, for example, is that routes using caching via
this implementation must preserve the exact array that's returned by the fetch
call all the way through the Ember stack to what's rendered.