123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /**
- * @module RESTController
- */
- import * as debugStuff from 'debug'
- const debug = debugStuff.debug('dbApiRESTCtrl')
- import { Router } from 'express'
- const MAX_RESULTS = 100
- /**
- * REST controller for MongoDB backend.
- */
- class RESTController {
- /**
- * Generates a controller for a model type.
- *
- * @param {mongoose.Model} mongoose model to use
- * @param {key} Key to use as index. Default is '_id'
- * @return {null}
- */
- constructor (model, key = '_id', subDocuments = {}) {
- this.model = model
- this.modelName = model.modelName.toLowerCase()
- this.key = key
- this.findOptions = {}
- this.findCriteria = {}
- this.extendData = (data) => data
- this.updateExtendedData = (data) => data
- this.subDocuments = subDocuments
- debug('created RESTController', this.modelName)
- }
- /**
- * Creates a DB item.
- *
- * @param {object} data object
- * @return {Promise}
- */
- create (data) {
- debug('create data item', data)
- const newData = this.extendData(data)
- const p = this.model
- .create(newData)
- .then(instance => {
- debug('created instance', instance)
- return instance
- })
- // debug('create return value', p)
- return p
- }
- /**
- * Read a DB item.
- *
- * @param {String} id
- * @return {Promise}
- */
- read (id) {
- debug('reading data item', id)
- const filter = {}
- filter[this.key] = id
- const p = this.model
- .findOne(filter)
- .then(instance => {
- debug('read instance', instance)
- return instance
- })
- // debug('read return value', p)
- return p
- }
- /**
- * Get a list of all DB items.
- *
- * @return {Promise}
- */
- list () {
- debug('reading data list')
- const p = this.model
- .find({})
- .limit(MAX_RESULTS)
- .then(instance => {
- debug('read list instance', instance)
- return instance
- })
- // debug('read return value', p)
- return p
- }
- /**
- * Update a DB item.
- *
- * @param {String} id
- * @param {String} data
- * @return {Promise}
- */
- update (id, data) {
- debug('update data item', id, data)
- const filter = {}
- filter[this.key] = id
- const p = this.model
- .findOne(filter)
- .then(instance => {
- debug('found data instance', instance)
- for (let attribute in data) {
- if (data.hasOwnProperty(attribute) && attribute !== this.key && attribute !== '_id') {
- instance[attribute] = data[attribute]
- }
- }
- return instance.save()
- })
- .then(instance => {
- debug('updated data instance', instance)
- return instance
- })
- // debug('read return value', p)
- return p
- }
- /**
- * Delete a DB item.
- *
- * @param {String} id
- * @return {Promise}
- */
- delete (id) {
- debug('delete data item')
- const filter = {}
- filter[this.key] = id
- const p = this.model
- .remove(filter)
- .then(() => {
- return {}
- })
- // debug('read return value', p)
- return p
- }
- route (parent = undefined) {
- const router = new Router({mergeParams: true})
- router.get('/', (req, res) => {
- this
- .list()
- .then(data => res.json(data))
- .catch(error => res.status(404).send(error))
- })
- router.post('/', (req, res) => {
- this
- .create(req.body)
- .then(data => res.json(data))
- .catch(error => res.status(404).send(error))
- })
- router.get('/:key', (req, res) => {
- this
- .read(req.params.key)
- .then(data => res.json(data))
- .catch(error => res.status(404).send(error))
- })
- router.put('/:key', (req, res) => {
- this
- .update(req.params.key, req.body)
- .then(data => res.json(data))
- .catch(error => res.status(404).send(error))
- })
- router.delete('/:key', (req, res) => {
- this
- .delete(req.params.key)
- .then(data => res.json(data))
- .catch(error => res.status(404).send(error))
- })
- Object.keys(this.subDocuments).forEach(key => {
- router.use(`/:parentKey/${key}`, this.subDocuments[key].route())
- })
- return router
- }
- }
- export default RESTController
|