Contribute on GitHub

Getting started

npm install express-restify-mongoose --save

Express 4 app

This snippet...

var express = require('express')
var bodyParser = require('body-parser')
var methodOverride = require('method-override')
var mongoose = require('mongoose')
var restify = require('express-restify-mongoose')
var app = express()
var router = express.Router()

app.use(bodyParser.json())
app.use(methodOverride())

mongoose.connect('mongodb://localhost/database')

restify.serve(router, mongoose.model('Customer', new mongoose.Schema({
name: { type: String, required: true },
comment: { type: String }
})))

app.use(router)

app.listen(3000, function () {
console.log('Express server listening on port 3000')
})

...automatically generates those endpoints.

GET http://localhost/api/v1/Customers/count
GET http://localhost/api/v1/Customers
PUT http://localhost/api/v1/Customers
POST http://localhost/api/v1/Customers
DELETE http://localhost/api/v1/Customers

GET http://localhost/api/v1/Customers/:id
GET http://localhost/api/v1/Customers/:id/shallow
PUT http://localhost/api/v1/Customers/:id
POST http://localhost/api/v1/Customers/:id
DELETE http://localhost/api/v1/Customers/:id

Usage with request

var query = {
$or: [{
name: '~Another'
}, {
$and: [{
name: '~Product'
}, {
price: '<=10'
}]
}],
price: 20
}

request({
url: '/api/v1/Model',
qs: {
query: encodeURIComponent(JSON.stringify(query))
}
})

Query

Operators

GET http://localhost/api/v1/Customers?name=~regex
GET http://localhost/api/v1/Customers?name=value
GET http://localhost/api/v1/Customers?name=>value
GET http://localhost/api/v1/Customers?name=>=value
GET http://localhost/api/v1/Customers?name=<value
GET http://localhost/api/v1/Customers?name=<=value
GET http://localhost/api/v1/Customers?name=!=value
GET http://localhost/api/v1/Customers?select=name
GET http://localhost/api/v1/Customers?select=-name

Sort, skip and limit

GET http://localhost/api/v1/Customers?sort=name
GET http://localhost/api/v1/Customers?sort=-name
GET http://localhost/api/v1/Customers?skip=10&limit=10

Populate

Populated fields will not have any effect on select fields as supported by Mongoose, they will be fetched along with select fields.

GET http://localhost/api/v1/Invoices?populate=customer
GET http://localhost/api/v1/Invoices?populate=customer&select=amount
GET http://localhost/api/v1/Invoices?populate=customer&select=customer.name
GET http://localhost/api/v1/Invoices?populate=customer&select=customer,amount
GET http://localhost/api/v1/Invoices?populate=customer&select=customer.name,amount

Reference

serve

restify.serve(router, model[, options])

router: express.Router() instance (Express 4), app object (Express 3) or server object (restify)

model: mongoose model

options: object type default version

  • prefix string /api

    Path to prefix to the REST endpoint.

  • version string /v1

    API version that will be prefixed to the rest path.

    If prefix or version contains /:id, then that will be used as the location to search for the id.

    Example

    version: '/v1/Entities/:id' generates /api/v1/Entities/:id/Model and /api/v1/Entities/Model for all pertinent methods

  • idProperty string _id

    findById and findByIdAnd* methods will query on the given property

  • middleware function | array

    An Express middleware or an array of Express middlewares that will be called after prereq and before access.

    Example
    middleware: function (req, res, next) {
    console.log('Incoming %s request', req.method)
    }
  • prereq function

    Returns or yields true or false. It is called on POST, PUT and DELETE requests and sends 403 (Forbidden) on false.

    Examples

    Sync

    prereq: function (req) {
    if (req.isAuthenticated()) {
    return true
    }
    
    return false
    }

    Async

    prereq: function (req, cb) {
    performAsyncLogic(function (err, result) {
    cb(err, true)
    })
    }
  • access function

    Returns or yields 'private', 'protected' or 'public'. It is called on GET, POST and PUT requests and filters out the fields defined in private and protected.

    Examples

    Sync:

    access: function (req) {
    if (req.isAuthenticated()) {
    return req.user.isAdmin ? 'private' : 'protected'
    } else {
    return 'public'
    }
    }

    Async

    access: function (req, cb) {
    performAsyncLogic(function (err, result) {
    cb(err, 'public')
    })
    }
  • restify boolean false

    Enable support for restify instead of Express.

  • plural boolean false

    Automatically pluralize the model's name using inflection.

  • lowercase boolean false

    Whether to call .toLowerCase() on the model's name before generating the routes.

  • name string the model's name

    The endpoint's name.

  • limit number

    Set a hard limit on the number of documents to return. Cannot be overriden by the client.

  • onError function send the entire mongoose error

    Leaving this as default will leak information about your database.

    A function with the signature function (err, req, res, next) that is used to output an error. err is the error object that is returned by mongoose.

    Example
    onError: function (err, req, res, next) {
    next(err)
    }
  • outputFn function

    A function with the signature function (req, res, result) that is used to output the result. res is a restify or express response object and result is the data returned by mongoose.

    Example
    outputFn: function (req, res, result) {
    if (result.length > 100) {
    result.length = 100
    }
    
    res.status(200).json(result)
    }
  • private array

    Array of fields which are only to be returned by queries that have private access.

    Example
    private: ['topSecret', 'fields']
  • protected array

    Array of fields which are only to be returned by queries that have private or protected access.

    Example
    private: ['somewhatSecret', 'keys']
  • postProcess function

    A middleware to be called after a successful response has been sent. If an error is sent to the client, this is not called.

    Example
    postProcess: function (req, res, next) {
    console.log('Successful %s request', req.method)
    }
  • lean boolean true

    Whether or not mongoose should use .lean() to convert results to plain old JavaScript objects. This is bad for performance, but allows returning virtuals, getters and setters.

  • findOneAndUpdate boolean true

    If false, will first find documents by id and then call save, allowing document middleware to be called. For more information regarding mongoose middleware, read the docs.

  • findOneAndRemove boolean true

    If false, will first find documents by id and then call remove, allowing document middleware to be called. For more information regarding mongoose middleware, read the docs.

  • contextFilter function

    A function with the signature function (model, req, cb) that allows request specific filtering.

    Example
    contextFilter: function (model, req, cb) {
    cb(model.find({
    user: req.user._id
    }))
    }
  • postCreate function

    A function with the signature function (res, result, done) which is run after creating a document.

  • postUpdate function v1.1.0

    A function with the signature function (res, result, done) which is run after updating a document.

  • postDelete function

    A function with the signature function (res, result, done) which is run after deleting a document.

defaults

restify.defaults(options)

options: same as above, sets this object as the defaults for anything you .serve() afterwards.