We’ve been working on a new UI and front-end architecture for our communication tool, Ginger. In doing so, we built a new JavaScript library to communicate with our django-rest-framework powered API(s).

Inspired by hood.ie but aimed at custom API back-ends, Amygdala was born out of the desire to reduce the complexity involved with managing multiple JavaScript modules (controllers or models/collections) that do essentially the same thing, fetch and sync data.

The result is a single module where you define your schema, API settings and you're done.

var store = new Amygdala({
  'config': {
    'apiUrl': 'http://localhost:8000',
    'localStorage': true
  },
  'schema': {
    'users': {
      'url': '/api/v2/user/'
    },
    'teams': {
      'url': '/api/v2/team/',
      'orderBy': 'name'
    },
    'discussions': {
      'url': '/api/v2/discussions/'
    }
  }
});
// GET
store.get('users').done(function() { ... });
// POST
store.add('teams', {'name': 'Lincoln Loop', 'active': true}).done(function() { ... });
// PUT
store.update('users', {'url': '/api/v2/user/32/', 'username': 'amy82', 'active': true}).done(function() { ... });
// DELETE
store.remove('users', {'url': '/api/v2/user/32/'}).done(function() { ... });

Whenever one of the above methods are called, the resulting response data is stored on a local cache, which is very handy when you want to minimize network requests, such as in mobile and realtime applications.

To access the cached data, there are only a couple methods you need to know about:

// Get the list of active users from the local cache
 var users = store.findAll('users', {'active': true});

 // Get a single user from the local cache
 var user = store.find('users', {'username': 'amy82'});

We currently have very basic offline read-only support through localStorage. One way we’re using it is to load the cached data and render our app immediately while fetching the new data in the background.

// get data from the cache (on the view’s render method)
var discussions = store.findAll('discussions', {'team': this.props.team.url}) || [];

// fetch the most recent discussions for the team
store.get('discussions', { 'team__slug': this.props.team.slug}).done(function() {
    // re-render our view
});

Or you can simply listen to changes, which will be triggered when you call the get, update, add or remove methods.

store.on('discussions:change', function() {
   // re-render our view
}.bind(this));

We’re far from done and we’d love your feedback and/or contributions. If you’re interested in Amygdala, download it from npm, check out the Github repo or come say hi at #lincolnloop on Freenode.