RESTful HTTP client for JavaScript powered web applications

Related tags

API amygdala
Overview

Amygdala logo

Amygdala is a RESTful HTTP library for JavaScript powered web applications. Simply configure it once with your API schema, and easily do GET, POST, PUT and DELETE requests with minimal effort and a consistent API.

Examples:

// GET
store.get('users').done(function() { ... });

// POST
store.add('teams', {'name': 'Lincoln Loop', 'active': true}).done(function() { ... });

browser support

How it works

1. INSTALL

NPM/Browserify

npm install amygdala.

Bower

bower install amygdala

Browser

Download the latest amygdala.js file. Minified/build version coming soon.

Dependencies:

2. SETUP

To create a new store, define the few possible settings listed below and your API schema.

var store = new Amygdala({
  'config': {
    'apiUrl': 'http://localhost:8000',
    'idAttribute': 'url',
    'headers': {
      'X-CSRFToken': getCookie('csrftoken')
    },
    'localStorage': true
  },
  'schema': {
    'users': {
      'url': '/api/v2/user/'
    },
    'teams': {
      'url': '/api/v2/team/',
      'orderBy': 'name',
      'oneToMany': {
        'members': 'members'
      },
      parse: function(data) {
        return data.results ? data.results : data;
      },
    },
    'members': {
      'foreignKey': {
        'user': 'users'
      }
    }
  }
});

Configuration options:

  • apiUrl - Full path to your base API url (required).
  • idAttribute - global primary key attribute (required).
  • headers - Any headers that you need to pass on each API request.
  • localStorage - enable/disable the persistent localStorage cache.

Schema options:

  • url - relative path for each "table" (required)
  • orderBy - order by which you want to retrieve local cached data. eg (name, -name (for reverse))
  • parse - Accepts a parse method for cases when your API also returns extra meta data.
  • idAttribute - overrides key attribute (if different in this schema)

Schema relations:

When you want to include related data under a single request, for example, to minimize HTTP requests, having schema relations allows you to still have a clean separation when interacting with the data locally.

Consider the following schema, that defines discussions that have messages, and messages that have votes:

var store = new Amygdala({
    'config': {
      'apiUrl': 'http://localhost:8000',
      'idAttribute': 'url'
    },
    'schema': {
      'discussions': {
        'url': '/api/v2/discussion/',
        'oneToMany': {
          'children': 'messages'
        }
      },
      'messages': {
        'url': '/api/v2/message/',
        'oneToMany': {
          'votes': 'votes'
        },
        'foreignKey': {
          'discussion': 'discussions'
        }
      },
      'votes': {
        'url': '/api/v2/vote/'
      }
    }
  }
);

In this scenario, doing a query on a discussion will retrieve all messages and votes for that discussion:

store.get('discussions', {'url': '/api/v2/discussion/85273/'}).then(function(){ ... });

Since we defined relations on our schema, the message and vote data won't be stored on the discussion "table", but on it's own "table" instead.

OneToMany:
'oneToMany': {
  'children': 'messages'
}

OneToMany relations are the most common, and should be used when you have related data in form of an array. In this case, children is the attribute name on the response, and messages is the destination "table" for the array data.

foreignKey:
'foreignKey': {
  'discussion': 'discussions'
}

foreignKey relations are basically for one to one relations. In this case Amygdala will look for an object as value of discussion and move it over to the discussions "table" if one is found.

3. USAGE

Querying the remote API server:

The methods below, allow you to make remote calls to your API server.

// 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() { ... });

In memory storage API:

On top of this, Amygdala also stores a copy of your data locally, which you can access through a couple different methods:

Find and filtering:
// Get the list of active users from memory
var users = store.findAll('users', {'active': true});

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

// Get a single user by id for memory
var user = store.find('users', 1103747470);

If you enable localStorage, the data is kept persistently. Because of this, once you instantiate Amygdala, your cached data will be loaded, and you can use it right away without having to wait for the remote calls. (We do not recommend using localStorage for production yet)

Fetching related data:

By defining your schema and creating relations between data, you are then able to query your data objects for the related objects.

In the example schema above, discussions have a oneToMany relation with messages, and messages have a foreignKey relation back to discussions. This is how it you can use them.

// Fetching related messages for a discussion (oneToMay)
var messages = store.find('discussions', '/api/v2/discussion/85273/').getRelated('messages');

// Getting the discussion object from a message (foreignKey)
var discussion = store.find('message', '/api/v2/message/81273/').getRelated('discussion');

Note that Amygdala doesn't fetch data automagically for you here, so it's up you to fetch it before running the query.

Events

Amygdala uses Wolfy87/EventEmitter under the hood to trigger some very basic events. Right now it only triggers two different events:

  • change
  • change:type

To listen to these events, you can use any of Event Emitter's binding methods or the aliases, the most common one being on:

// Listen to any change in the store
store.on('change', function() { ... });

// Listen to any change of a specific type
store.on('change:users', function() { ... });
Comments
  • option to override idAttribute in schema

    option to override idAttribute in schema

    There are APIs that use natural keys and do not provide synthetic, uniform ID attribute. This adds support for providing schema specific attribute that contains unique identification string.

    opened by smokku 2
  • Question about Performance

    Question about Performance

    Do you have experience about handling big data sets? I found this blog post: http://josh.zeigler.us/technology/web-development/how-big-is-too-big-for-json/ Do you have numbers like that with Amygdala ?

    opened by n3ssi3 1
  • How to catch errors

    How to catch errors

    I have deletePlace function in my project. When I send DELETE without authorization to some resource server I've got the error 401, how can I catch errors in amygdala?

    this.deletePlace = function(place_id) {
        return store.remove('places', {
            'id': "/" + place_id
        }).done(function() {
            ee.emit('change');
        })
    }
    

    Error example caused by lack of authorization

    DELETE http://localhost/api/v1/places/qx9143jmj7 401 (Unauthorized)
    XHR finished loading: DELETE "http://localhost/api/v1/places/qx9143jmj7"
    Uncaught #<XMLHttpRequest>
    
    opened by arkadiusz-wieczorek 1
  • Unable to build GET /api/users/(id) type urls?

    Unable to build GET /api/users/(id) type urls?

    I can't seem to figure out how to build urls that follow the /api/endpoint/(id) pattern. It seems this library does it by doing /api/endpoint?id=1 instead. Does this library not support the former pattern?

    opened by jkehler 1
  • Are remote accesses automatic?

    Are remote accesses automatic?

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

    What happens if the localstorage returns nothing, for example, its the first access, does it trigger a get on the remote resource? Thanks

    opened by kokujin 1
  • No Backbone/jQuery

    No Backbone/jQuery

    This is based on the feature/tooling branch, so make sure to review and merge that request first before reviewing this one, and you won't see both sets of changes at once.

    • Removes Backbone (and, implicitly, jQuery)
    • Adds Q for promises (2.5kb gzipped)
    • Mocks the browser's XMLHttpRequest object so that we can successfully test in Node (we should use this strategy for Threads)
    • Tests get, add, update, and remove
    opened by bkonkle 0
  • Tooling & UMD wrapping

    Tooling & UMD wrapping

    • Adds a .jshintrc
    • Adds an .editorconfig to keep the style consistent
    • Adds a UMD wrapper that allows it to be used with AMD, CommonJS, and browser globals, while keeping the core source free of compatibility decorators
    • Adds a gulpfile to manage the building of the UMD browser distribution, and to minify the dist build

    Confirmed that all tests pass.

    opened by bkonkle 0
  • handle empty array from server

    handle empty array from server

    If the server responds with no items in the array this is not currently ignored and not reflected to the local store.

    Change to handle empty response array and override current store[type] with {}

    opened by fridaystreet 0
  • find doesn't work if ids are numerical

    find doesn't work if ids are numerical

    .find('users', 1) doesn't return anything. You need to parse the number in as a string .find('users', '1')

    The find function doesn't have support for numerical ids. Possible to just change line 503

    } else if (Object.prototype.toString.call(query) === '[object String]') {

    to

    } else if (Object.prototype.toString.call(query) === '[object String]' || Object.prototype.toString.call(query) === '[object Number]') {

    Cheers Paul

    ps nice little library, lots of potential.

    opened by fridaystreet 0
  • update() does not use apiUrl and schema url

    update() does not use apiUrl and schema url

    I have the fallowing instance configured:

    this.store = new Amygdala({
          'config' : {
            'apiUrl' : 'http://localhost:8081',
            'idAttribute': 'url',
          },
          'schema' : {
            'plans' : {
              'url' : '/plans/'
            }
          }
        });
    

    this.store.get('plans', {'url': 'myid'}) resolves correctly to http://localhost:8081/plans/myid

    but

    this.store.update('plans', {'url':'myid', data:data}) resolves to http://localhost:8080/myid

    The webserver serving the app is running on http://localhost:8080 while a I have the REST API on http://localhost:8081

    opened by johndevs 0
  • Add an option for appending trailing slash

    Add an option for appending trailing slash

    Django will redirect if missing trailing slashes, but this will only work for GET. Redirects will also not work if doing a cross origin request while developing (eg localhost:4000 -> localhost:8000)

    opened by shangxiao 1
  • Auto-append params and post body values from config

    Auto-append params and post body values from config

    The FR is for auth in mind. Most APIs that use authentication require you to append a token on every request either as a query param or in the post body. Setting that to a variable in the config object would be super convienient for calling an api behind oauth2.

    opened by beriberikix 1
  • Support for uri-parameters in API endpoints

    Support for uri-parameters in API endpoints

    Use cases:

    • user has oneToMany coupons, and coupons are retrieved via /api/v1/user/{user_id}/coupons
    • API endpoint requires a parameter (no GET all), /api/v1/notes/{user_id}/

    This can be achieved via query parameters right now, but may not be a fit for everyone and requires a certain type of structure for the API endpoints that may not be possible to change.

    enhancement 
    opened by mlouro 4
Releases(0.4.2)
Owner
Lincoln Loop
Makers of high performance web applications.
Lincoln Loop
Promise based HTTP client for the browser and node.js

axios Promise based HTTP client for the browser and node.js New axios docs website: click here Table of Contents Features Browser Support Installing E

axios 98k Jan 3, 2023
🤠 An opinionated AJAX client for Ruby on Rails APIs

Rails Ranger Exploring the routes and paths of Ruby on Rails APIs Github Repository | Documentation Rails Ranger is a thin layer on top of Axios, whic

Victor Marques 37 Nov 22, 2022
JavaScript OAuth 1.0a signature generator (RFC 5849) for node and the browser

OAuth 1.0a signature generator for node and the browser Compliant with RFC 5843 + Errata ID 2550 and community spec Installation Install with npm: npm

Marco Bettiolo 230 Dec 16, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Node.js web server framework for Http/1.1 or Http/2

Node.js web server framework for Http/1.1 or Http/2 Description: This is http framework, you can use it to create Http/1.1 or Http/2 service。 Now let'

Jeremy Yu 10 Mar 24, 2022
📡Usagi-http-interaction: A library for interacting with Http Interaction API

?? - A library for interacting with Http Interaction API (API for receiving interactions.)

Rabbit House Corp 3 Oct 24, 2022
Codrops 135 Dec 12, 2022
Processing Foundation 18.6k Jan 1, 2023
RESTful degradable JavaScript routing using pushState

Davis.js Description Davis.js is a small JavaScript library using HTML5 history.pushState that allows simple Sinatra style routing for your JavaScript

Oliver Nightingale 532 Sep 24, 2022
🌳 Tiny & elegant JavaScript HTTP client based on the browser Fetch API

Huge thanks to for sponsoring me! Ky is a tiny and elegant HTTP client based on the browser Fetch API Ky targets modern browsers and Deno. For older b

Sindre Sorhus 8.5k Jan 2, 2023
🚀 Blazing Fast S3 Powered CDN ✨ Powered By Fastify, S3 Buckets & Docker!

?? WasiCDN Blazing Fast S3 Powered CDN, Powered By Fastify, S3 Compatible Buckets & Docker! Core DockerHub: https://hub.docker.com/r/maximking19/wasic

Maxim 5 Aug 31, 2022
T3 is a client-side JavaScript framework for building large-scale web applications

Box has migrated using react, webpack, and the latest version of ECMAScript for our frontend projects as of 2018. We no longer support chan

Box 1.6k Dec 8, 2022
A Node.js HTTP proxy that tracks managed PaaS account applications and auto-stop&start them

paastis-engine Features Paastis engine is the heart of the Paastis project. Its goal is to monitor and manage (start & stop) PaaS applications based o

null 14 Nov 8, 2022
🚀 A RESTful API generator for Node.js

A RESTful API generator rest-hapi is a hapi plugin that generates RESTful API endpoints based on mongoose schemas. It provides a powerful combination

Justin Headley 1.2k Dec 31, 2022
A jQuery plugin for easy consumption of RESTful APIs

jQuery REST Client v1.0.1 Summary A jQuery plugin for easy consumption of RESTful APIs Downloads Development Version Production Version File Size Repo

Jaime Pillora 618 Nov 20, 2022
A boilerplate for building production-ready RESTful APIs using Node.js, Express, and Mongoose

By running a single command, you will get a production-ready Node.js app installed and fully configured on your machine. The app comes with many built-in features, such as authentication using JWT, request validation, unit and integration tests, continuous integration, docker support, API documentation, pagination, etc. For more details, check the features list below.

Hagop Jamkojian 5k Dec 31, 2022
Framework for setting up RESTful JSON APIs with NodeJS.

Restberry works with both Express and Restify! Framework for setting up RESTful JSON APIs with NodeJS. Define your models and setup CRUD API calls wit

Restberry 117 Jul 5, 2021
RESTful API using Hapi NodeJs Framework. This app is project from Dicoding Couses, Belajar Membuat Aplikasi Back-end untuk Pemula

RESTful API using Hapi NodeJs Framework. This app is project from Dicoding Couses, Belajar Membuat Aplikasi Back-end untuk Pemula

Muhammad Ferdian Iqbal 1 Jan 3, 2022