weare-api
v0.1.5
Published
A module to help build Mongoose-based REST APIs.
Downloads
6
Readme
[TOC]
WE_ARE API
A module to help build mongoose-based REST APIs. Sends responses using the weare-ajax-response module. Tests cover ~90% of the code.
Installation
$ npm install weare-api
Running the tests
To run the unit tests, you must install the dev dependencies: npm install --only-dev
. Then, you only have to execute npm test
.
Usage
var api = require('weare-api')(router);
The return value is an instance of WeareApi
with the following properties :
router
The same object that you passed as an argument when you initialized the module.
parseParams
An object with the following functions:
parseGet(req, paramsDefinition)
Parses GET parameters (req.query
) and puts them into req.parsedQuery
parsePost(req, paramsDefinition)
Parses POST parameters (req.body
) and puts them into req.parsedBody
parse(req, paramsDefinition, values, parsedObjectName)
The function used by parseGet and parsePost
The paramsDefinition
arguments is an object defining the parameters to parse - here's an example :
{
paramName1: {
type: 'integer|float|date'
required: boolean
default: 'optional value'
},
...
}
| Types | Validators | |---|---| | string | required, regExp, enum, minlength | | integer | required, min, max | | float | required, min, max | | boolean | required | | date | required |
restify(options)
Creates api endpoints (getAll, getOne, create, update, order, delete) for a model. Example:
var News = require('../../models/News');
api.restify({
route: 'news',
model: News,
modelName: 'news',
select: '-__v',
populate: '_image _category',
sort: { 'date' : 'desc' },
pagination: {defaults: { number: 20 } },
populateOne: '_image _category',
disabled: [
'create',
'update',
'delete'
],
hooks: {
getAll: {
// filter by category
buildQuery: function(query, req, res, options, callback) {
var parseErrors = api.parseParams.parseGet(req, {
category: {
type: 'string',
default: null
},
});
if (parseErrors !== null) {
ajaxResponse(res).badRequest(parseErrors);
return callback('error');
}
if(req.parsedQuery.category) {
query.where('_category', req.parsedQuery.category);
}
callback(null, query);
},
},
}
});
View all the possible options by clicking here.
Hooks
Hooks are functions that can either modify a query before its execution or modify the data before sending it back to the client. You can send your own error responses back to the client, else the module will automatically send an "internalServerError" response. Available hooks are listed below.
Route types
getOne - GET /:route/:id
Gets a document by id.
buildQuery(query, req, res, options, callback) hook
Called before executing the findOne
query.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedQuery)
.
modifyResult(item, req, res, options, callback) hook
Called before returning the json-ified item back to the client.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedItem)
.
getAll - GET /:route
Gets a list of documents.
buildQuery(query, req, res, options, callback) hook
Called before executing the find
query.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedQuery)
.
modifyResults(responseData, req, res, options, callback) hook
Called before returning the data back to the client. Warning: The responseData format will be different whether you have enabled the pagination or not.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedResponseData)
.
create - POST /:route
Creates a new document.
beforeSave(document, req, res, options, callback) hook
Called right before saving the item to the database.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedDocument)
.
afterSave(document, req, res, options, callback) hook
Called right after the item has been saved into the database.
The callback function should be called with 1 argument: callback(err)
.
update - PUT /:route/:id
Updates a document by id.
buildQuery(query, req, res, options, callback) hook
Called before executing the findOne
query.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedQuery)
.
beforeSave(document, req, res, options, callback) hook
Called right before saving the item to the database.
The callback function should be called with 1 or 2 arguments: callback(err, modifiedDocument)
.
afterSave(document, req, res, options, callback) hook
Called right after the item has been saved into the database.
The callback function should be called with 1 argument: callback(err)
.
order - PUT /:route/:id/order
Updates a document order. The new order is passed in the request body: { "order" : Number }
Adjusts the other documents' orders in the collection, depending on the options that where passed to api.restify
.
delete - DELETE /:route/:id
Deletes a document by id.
Also calls the model's static method deleteAssets
if it is defined.
beforeDelete(document, req, res, options, callback) hook
Called right before deleting the item from the database.
The callback function should be called with 1 argument: callback(err)
.
afterDelete(document, req, res, options, callback) hook
Called right after the item has been deleted from the database.
The callback function should be called with 1 argument: callback(err)
.
routeTo(route, routeType, req, res)
Programmatically call a route.
Example: api.routeTo('news', 'getOne', req, res);
will forward the current request to the news getOne api route.
Groups
You can create grouped middlewares and hooks configs, that will be applied to all the REST APIs belonging to that group. Example:
api.addGroup('cms', {
middlewares: {
'*': [ CMSAuthMiddleware ],
'getAll': [ CMSPermissionsMiddleware.read ],
'getOne': [ CMSPermissionsMiddleware.read ],
'update': [ CMSPermissionsMiddleware.edit ],
'order': [ CMSPermissionsMiddleware.edit ],
'create': [ CMSPermissionsMiddleware.edit ],
'delete': [ CMSPermissionsMiddleware.delete ],
}
});
Then, we create a REST API that will be in that group:
api.restify({
route: 'retailers',
model: Retailers,
groups: ['cms'],
});
Changelog
0.1.2
- added option to use "toJSON()" instead of "toObject()" for result output
0.1.1
- improved code readability
- added "groups" support
0.1.0
- initial version