mio
RESTful resources for both client and server.
Mio provides a common model layer between client and server for building REST
APIs and web applications.
Mio provides a consistent API across client and server for querying,
manipulating, and persisting data. Create a REST API server from your mio
resources and interact with them from the browser using the same interface. No
need for any route handling or AJAX boilerplate.
Mio models are designed to be RESTful and avoid leaky abstractions for mapping
to HTTP methods. For example, providing Resource.get()
instead of findOne()
and Resource.post()
where most libraries would provide create()
.
- Small readable core (only ~300 SLOC)
- Simple enumerable objects
- Hooks and events before and after CRUD operations and object lifecycle
- Backbone-style API for extending resources
- Modular. Plugins provide storage, validation, etc.
- Browser and node.js support
Installation
Using npm:
npm install --save mio
Using bower:
bower install --save mio
Using browser script tag and global (UMD wrapper):
// Available via window.mio
<script src="dist/mio.js"></script>
API
See the full API documentation.
Examples
Resources
Define new resources by extending the base Resource
class. You can pass
attribute definitions to .extend()
or use the chainable .attr()
:
var User = mio.Resource.extend({
attributes: {
id: { primary: true },
name: { required: true },
active: { default: false },
created: {
default: function() {
return new Date();
}
}
},
sayHello: function() {
return "Hello I'm " + this.name;
}
});
var user = new User({ name: 'Mio' });
user.sayHello();
Queries
Query methods provide a consistent interface for fetching resources.
Storage plugins use the asynchronous events provided for each method to fetch or
persist resources to a database.
Find one user:
User.get(123, function(err, user) {
});
Find all users matching a query:
User.Collection.get({ active: true }, function (err, users) {
});
Using a chainable query builder:
User.Collection.get()
.where({ active: true })
.sort({ created_at: "desc" })
.size(10)
.exec(function(err, users) {
});
See the API documentation for a complete list of query methods
and event information.
Plugins
Resources may use plugin functions which extend them with functionality such
as validation, persistence, etc.
var mio = require('mio');
var MongoDB = require('mio-mongo');
var User = mio.Resource.extend();
User.use(MongoDB({
url: 'mongodb://db.example.net:2500'
}));
Browser or server specific plugins:
User.browser(plugin);
User.server(plugin);
Hooks
Before and after hooks are provided for CRUD operations and resource lifecycle
events. Hooks are asynchronous and execute in series.
User.before('get', function (query, next) {
});
User.on('patch', function (query, changed) {
});
See the full documentation for events.
Relations
Define relationships between resources in combination with a supporting storage
plugin.
Author.hasMany('books', {
target: Book,
foreignKey: 'author_id'
});
Book.belongsTo('author', {
target: Author,
foreignKey: 'author_id'
});
Book.get(1).withRelated(['author']).exec(function(err, book) {
console.log(book.author);
});
See the relations API for more
information.
REST API
Create a REST API server from your resources and interact with them from the
browser using the same interface. No need for any route handling or AJAX
boilerplate. Automatic client-server communication is provided by
mio-ajax in the browser and
mio-express on the server.
Create a Resource definition shared between browser and server:
var mio = require('mio');
var Validators = require('mio-validators');
var User = module.exports = mio.Resource.extend({
attributes: {
id: { primary: true },
name: {
required: true,
constraints: [Validators.Assert.Type('string')]
},
created: {
required: true,
constraints: [Validators.Assert.Instance(Date)],
default: function () {
return new Date();
}
}
}
}, {
baseUrl: '/users'
});
Extend it on the server with server-specific plugins:
var User = require('./models/User');
var MongoDB = require('mio-mongo');
var ExpressResource = require('mio-resource');
var express = require('express');
User
.use(MongoDB({
url: 'mongodb://db.example.net:2500'
}))
.use(ExpressResource.plugin());
var app = express();
app.use(User.router);
app.listen(3000);
And in the browser:
var User = require('./models/User');
var Ajax = require('mio-ajax');
User.use(Ajax());
var user = User().set({ name: "alex" }).post(function(err) {
});
MIT Licensed