sleepify
v1.1.1
Published
A library for quickly prototyping relational REST apis
Downloads
3
Readme
sleepify
An unobtrusive, easy to use library to quickly prototype relational REST apis in Express.
Install
npm i -S sleepify
Changes (v1.1.0)
- Plugin now accepts an express app or router as a first parameter. This was necessary to drop the express dependency.
//Previous behaviour
//let usersRouter = sleepify(userPlugin)
//Current behaviour
let usersRouter = express.Router()
sleepify(usersRouter, userPlugin)
//Equivalent
let usersRouter = sleepify(express.Router(), userPlugin)
//usersRouter points to the same router passed to it
Usage (TL;DR):
let express = require('express')
let bodyParser = require('body-parser')
let {sleepify, sleepymem} = require('sleepify')
let app = express()
app.use(bodyParser.json())
module.exports = app
//Dummy memorystore
let memDB = {}
memDB.cars = [
{id: '0', name: 'Suzuki'},
{id: '1', name: 'Honda'},
{id: '2', name: 'BMW'},
{id: '3', name: 'MX5'}
]
memDB.users = [
{
id: '0',
name: 'Foo',
cars: memDB.cars.slice(0, 2)
},
{
id: '1',
name: 'Bar',
cars: memDB.cars.slice(2, 3)
}
]
//sleepymem is a basic in-memory plugin
let userPlugin = sleepymem({
name: 'user',
model: memDB.users
})
.pre((req, res, next) => {
console.log(req.method + ' ' + req.originalUrl)
next()
})
.pre([ACTIONS.CREATE, ACTIONS.UPDATE, ACTIONS.DELETE], (req, res, next) => {
console.log(`Simulating authentication middleware`)
next()
})
.rel(sleepymem({
name: 'car',
model: memDB.cars,
expose: [ACTIONS.GET, ACTIONS.LIST, ACTIONS.REPLACE]
}).pre((req, res, next) => {
console.log('Cars middleware only!')
next()
}).pre(ACTIONS.CREATE, (req, res, next) => {
console.log('Before car creation')
next()
})
)
.post((req, res, next) => {
console.log(`Done ${req.method + ' ' + req.originalUrl}`)
next()
})
// This router will point to the following endpoints:
// GET /users
// GET /users/:userId
// POST /users
// PATCH /users/:userId
// DELETE /users/:userId
// GET /users/:userId/cars
// GET /users/:userId/cars/:carId
// PUT /users/:userId/cars/:carId
let usersRouter = express.Router()
sleepify(usersRouter, userPlugin)
let apiRouter = express.Router()
apiRouter.use(usersRouter)
app.use('/api/v1', apiRouter)
Plugin methods:
plugin.pre(action, middleware) / plugin.post(action, middleware)
:
action
: The action the middleware should be applied to. One of the actions fromACTIONS
.middleware
:function (req, res, next) / Array
- An express middleware or an array of them.
action
can be replaced by middleware
. This is equivalent to plugin.pre(ACTIONS.ALL, middleware)
or plugin.post(ACTIONS.ALL, middleware)
respectively.
plugin.rel(plugin)
:
plugin
: An instance of a plugin to be nested. Much like a nested router.
Plugins
Plugins are a way to define how an action should be performed.
A plugin takes an options
object:
options
:
name
:String
(required) - The prefix for these routes (for example'user'
).plural
:String
(optional, default:name + 's'
) - The prefix for these routes (for example'facilities'
).model
:AnyObject
(optional, default:undefined
) - An object representing the model to be interacted with. This is available later inreq.slp.model
expose
:Array
(optional, default:ACTIONS.ALL
) - The endpoints to expose.methods
:Object
(required, default:noop object
) - An object containing at least one of the actions defined inACTIONS
as a key with a value offunction (req, done)
describing the implementation of this specific method. Callback:done(statusCode / Error, responseObject)
.
Example:
{
name: 'facility',
plural: 'facilities',
model: mongoose.model('Facility'),
expose: [ACTIONS.GET, ACTIONS.LIST],
methods: {
get: (req, done) => {
req.slp.model.findById(req.slp.id)
.then(facility => {
if(!facility) return done(404)
done(200, facility)
}).catch(done)
},
list: (req, done) => {
req.slp.model.find({...})
.then(facilities => done(200, facilities))
.catch(done)
}
}
}
Extending plugins
An example implementation is available here.
MongoosePlugin
will be available soon in a different repo.
TODO
- [ ] Add support for collection delete.
- [x] Allow expose endpoint selection in Plugins.
- [ ] Add support for other node-based frameworks (koa, restify...).
Development
Install dependencies: npm i
Run tests: npm test