Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/beauby/jsonapi-datastore

JavaScript client-side JSON API data handling made easy.
https://github.com/beauby/jsonapi-datastore

json-api

Last synced: 5 days ago
JSON representation

JavaScript client-side JSON API data handling made easy.

Awesome Lists containing this project

README

        

# jsonapi-datastore
[![Build Status](https://travis-ci.org/beauby/jsonapi-datastore.svg)](https://travis-ci.org/beauby/jsonapi-datastore)

JavaScript client-side [JSON API](http://jsonapi.org) data handling made easy.

Current version is v0.4.0-beta. It is still a work in progress, but should do what it says.

## Description

The [JSONAPI](http://jsonapi.org) standard is great for exchanging data (which is its purpose), but the format is not ideal to work directly with in an application.
jsonapi-datastore is a JavaScript framework-agnostic library (but an [AngularJS version](#angularjs) is provided for convenience) that takes away the burden of handling [JSONAPI](http://jsonapi.org) data on the client side.

What it does:
- read JSONAPI payloads,
- rebuild the underlying data graph,
- allows you to query models and access their relationships directly,
- create new models,
- serialize models for creation/update.

What it does not do:
- make requests to your API. You design your endpoints URLs, the way you handle authentication, caching, etc. is totally up to you.

## Installing

Install jsonapi-datastore with `bower` by running:
```
$ bower install jsonapi-datastore
```
or with `npm` by running:
```
$ npm install jsonapi-datastore
```

## Parsing data

Just call the `.sync()` method of your store.
```javascript
var store = new JsonApiDataStore();
store.sync(data);
```
This parses the data and incorporates it in the store, taking care of already existing records (by updating them) and relationships.

## Parsing with meta data

If you have meta data in your payload use the `.syncWithMeta` method of your store.
```javascript
var store = new JsonApiDataStore();
store.syncWithMeta(data);
```
This does everything that `.sync()` does, but returns an object with data and meta split.

## Retrieving models

Just call the `.find(type, id)` method of your store.
```javascript
var article = store.find('article', 123);
```
or call the `.findAll(type)` method of your store to get all the models of that type.
```javascript
var articles = store.findAll('article');
```
All the attributes *and* relationships are accessible through the model as object properties.
```javascript
console.log(article.author.name);
```
In case a related resource has not been fetched yet (either as a primary resource or as an included resource), the corresponding property on the model will contain only the `type` and `id` (and the `._placeHolder` property will be set to `true`). However, the models are *updated in place*, so you can fetch a related resource later, and your data will remain consistent.

## Serializing data

Just call the `.serialize()` method on the model.
```javascript
console.log(article.serialize());
```

## Examples

```javascript
// Create a store:
var store = new JsonApiDataStore();

// Then, given the following payload, containing two `articles`, with a related `user` who is the author of both:
var payload = {
data: [{
type: 'article',
id: 1337,
attributes: {
title: 'Cool article'
},
relationships: {
author: {
data: {
type: 'user',
id: 1
}
}
}
}, {
type: 'article',
id: 300,
attributes: {
title: 'Even cooler article'
},
relationships: {
author: {
data: {
type: 'user',
id: 1
}
}
}
}]
};

// we can sync it:
var articles = store.sync(payload);

// which will return the list of synced articles.

// Later, we can retrieve one of those:
var article = store.find('article', 1337);

// If the author resource has not been synced yet, we can only access its id and its type:
console.log(article.author);
// { id: 1, _type: 'article' }

// If we do sync the author resource later:
var authorPayload = {
data: {
type: 'user',
id: 1,
attributes: {
name: 'Lucas'
}
}
};

store.sync(authorPayload);

// we can then access the author's name through our old `article` reference:
console.log(article.author.name);
// 'Lucas'

// We can also serialize any whole model in a JSONAPI-compliant way:
console.log(article.serialize());
// ...
// or just a subset of its attributes/relationships:
console.log(article.serialize({ attributes: ['title'], relationships: []}));
// ...
```

## Documentation

See [DOCUMENTATION.md](DOCUMENTATION.md).

## What's missing

Currently, the store does not handle `links` attributes or resource-level or relationship-level meta.

## Notes

### AngularJS

jsonapi-datastore is bundled with an AngularJs wrapper. Just include `ng-jsonapi-datastore.js` in your `index.html` and require the module `beauby.jsonApiDataStore` in your application.
You can then use the `JsonApiDataStore` factory, which is essentially defined as follows:
```javascript
{
store: new JsonApiDataStore(),
Model: JsonApiDataStoreModel
}
```
so that you can use it as follows:

```javascript
angular
.module('myApp')
.controller('myController', function(JsonApiDataStore) {
var article = JsonApiDataStore.store.find('article', 1337);
var newArticle = new JsonApiDataStore.Model('article');
newArticle.setAttribute('title', 'My cool article');
console.log(newArticle.serialize());
});
```

## Contributing

All pull-requests welcome!