Last active
August 29, 2015 14:01
-
-
Save dhigginbotham/f9626da2a0ebcb24f305 to your computer and use it in GitHub Desktop.
simple express rest app... yeah.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_ = require "lodash" | |
rest = (opts) -> | |
# simple prefix, ie http://localhost:1337/api/:collection/:id? | |
@prefix = '/api' | |
@path = null | |
@key = 'collection' | |
# pre doing db, so if you want to pass in some | |
# overrides, this is where you'd do it. | |
@preware = [] | |
# afterware, ie getting the object | |
@afterware = [] | |
# support method types | |
@supports = ['post', 'put', 'get', 'delete'] | |
@model = null | |
if opts? then _.extend @, opts | |
# define our context | |
self = @ | |
if not @path? | |
# define model path | |
@path = '/' + self.model.modelName.toLowerCase(); | |
# check if `path` has an 's' at the end | |
if @path[@path.length - 1] != 's' then @path += 's' | |
# router function | |
@router = (req, res, next) -> | |
method = req.method.toLowerCase() | |
return if self.supports.indexOf(method) == -1 then next(JSON.stringify({error: 'This is an unsupported/restricted method.'})) | |
switch method | |
when 'get' then self.get req, (err, resp) -> | |
return if err? then next err, null | |
req[self.key] = resp | |
next() | |
when 'post' then self.post req, (err, resp) -> | |
return if err? then next err, null | |
req[self.key] = resp | |
next() | |
when 'put' then self.put req, (err, resp) -> | |
return if err? then next err, null | |
req[self.key] = resp | |
next() | |
when 'delete' then self.delete req, (err, resp) -> | |
return if err? then next err, null | |
req[self.key] = resp | |
next() | |
@endpoint = (req, res) -> | |
res.json req[self.key] | |
@ | |
rest::get = (req, fn) -> | |
self = @ | |
id = if req.params.id then {_id: req.params.id} else {} | |
self.model.find id, (err, docs) -> | |
return if err? then fn err, null | |
fn null, docs | |
rest::save = (req, fn) -> | |
self = @ | |
newCollection = new self.model req.body | |
newCollection.save (err, docs) -> | |
return if err? then fn err, null | |
fn null, docs | |
rest::update = (req, fn) -> | |
self = @ | |
id = {_id: req.params.id} | |
update = _.omit(req.body, '_id') | |
self.model.update id, update, {upsert: true}, (err, updated) -> | |
# check for existence of errors | |
return if err? then fn err, null | |
fn null, updated | |
rest::post = (req, fn) -> | |
self = @ | |
if typeof req.params.id != 'undefined' then self.update req, (err, updated) -> | |
return if err? then fn err, null | |
fn null, updated | |
else self.save req, (err, saved) -> | |
return if err? then fn err, null | |
fn null, saved | |
rest::put = (req, fn) -> | |
self = @ | |
if typeof req.params.id != 'undefined' | |
self.update req, (err, updated) -> | |
return if err? then fn err, null | |
fn null, updated | |
else fn null, {error: 'You must include an \'/:id\' param'} | |
rest::delete = (req, fn) -> | |
self = @ | |
id = if req.params.id then {_id: req.params.id} else {} | |
self.model.remove id, (err, removed) -> | |
return if err? then fn err, null | |
fn null, removed | |
rest::mount = (app) -> | |
self = @ | |
uri = self.prefix + self.path + '/:id?' | |
app.all uri, self.preware, self.router, self.afterware, self.endpoint | |
module.exports = rest |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(function() { | |
var _ = require('lodash'); | |
function Rest(opts, app) { | |
//public options | |
this.prefix = '/api'; | |
this.path = null; | |
this.key = 'collection'; | |
this.preware = []; | |
this.afterware = []; | |
this.supports = ['post', 'put', 'get', 'delete']; | |
this.model = null; | |
// extend options | |
if (opts) _.extend(this, opts); | |
// maintain context | |
var self = this; | |
if (!this.path) { | |
this.path = '/' + this.model.modelName.toLowerCase(); | |
if (this.path[this.path.length-1] != 's') this.path += 's'; | |
} | |
this.router = function router(req, res, next) { | |
var method = req.method.toLowerCase(); | |
if (self.supports.indexOf(method) == -1) { | |
return next(JSON.stringify({ | |
error: 'This HTTP Method is unsuported' | |
}), null); | |
} | |
function defaultCallback(err, resp) { | |
if (err) return next(err, null); | |
req[self.key] = resp; | |
return next(); | |
}; | |
return self[method](req, defaultCallback); | |
}; | |
this.endpoint = function endpoint(req, res) { | |
return res.json(req[self.key]); | |
}; | |
return this.mount(app); | |
}; | |
Rest.prototype.createDocument = function _createDocument(req, fn) { | |
var newCollection = new this.model(req.body); | |
newCollection.save(fn); | |
}; | |
Rest.prototype.updateDocument = function _updateDocument(req, fn) { | |
var id = (req.params.id ? {_id: req.params.id} : null); | |
var update = _.omit(req.body, '_id'); | |
this.model.update(id, update, {upsert: true}, fn); | |
}; | |
Rest.prototype.mount = function _mount(app) { | |
var url = this.prefix + this.path + '/:id?'; | |
app.all(url, this.preware, this.router, this.afterware, this.endpoint); | |
return this; | |
}; | |
Rest.prototype.get = function _get(req, fn) { | |
var id = (req.params.id ? {_id: req.params.id} : {}); | |
this.model.find(id, fn); | |
}; | |
Rest.prototype.post = function _post(req, fn) { | |
if (req.params.id) { | |
this.updateDocument(req, fn); | |
} else { | |
this.createDocument(req, fn); | |
} | |
}; | |
Rest.prototype.put = function _put(req, fn) { | |
if (req.params.id) { | |
this.updateDocument(req, fn); | |
} else { | |
return fn(null, { | |
error: 'A valid id is required for this type of request' | |
}); | |
} | |
}; | |
Rest.prototype.delete = function _delete(req, fn) { | |
var id = (req.params.id ? {_id: req.params.id} : null); | |
this.model.remove(id, fn); | |
}; | |
if (typeof module != 'undefined' && module.exports) { | |
module.exports = Rest; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment