You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.1 KiB
188 lines
5.1 KiB
8 years ago
|
# 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!
|