RESTController.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * @module RESTController
  3. */
  4. import * as debugStuff from 'debug'
  5. const debug = debugStuff.debug('dbApiRESTCtrl')
  6. import { Router } from 'express'
  7. const MAX_RESULTS = 100
  8. /**
  9. * REST controller for MongoDB backend.
  10. */
  11. class RESTController {
  12. /**
  13. * Generates a controller for a model type.
  14. *
  15. * @param {mongoose.Model} mongoose model to use
  16. * @param {key} Key to use as index. Default is '_id'
  17. * @return {null}
  18. */
  19. constructor (model, key = '_id', subDocuments = {}) {
  20. this.model = model
  21. this.modelName = model.modelName.toLowerCase()
  22. this.key = key
  23. this.findOptions = {}
  24. this.findCriteria = {}
  25. this.extendData = (data) => data
  26. this.updateExtendedData = (data) => data
  27. this.subDocuments = subDocuments
  28. debug('created RESTController', this.modelName)
  29. }
  30. /**
  31. * Creates a DB item.
  32. *
  33. * @param {object} data object
  34. * @return {Promise}
  35. */
  36. create (data) {
  37. debug('create data item', data)
  38. const newData = this.extendData(data)
  39. const p = this.model
  40. .create(newData)
  41. .then(instance => {
  42. debug('created instance', instance)
  43. return instance
  44. })
  45. // debug('create return value', p)
  46. return p
  47. }
  48. /**
  49. * Read a DB item.
  50. *
  51. * @param {String} id
  52. * @return {Promise}
  53. */
  54. read (id) {
  55. debug('reading data item', id)
  56. const filter = {}
  57. filter[this.key] = id
  58. const p = this.model
  59. .findOne(filter)
  60. .then(instance => {
  61. debug('read instance', instance)
  62. return instance
  63. })
  64. // debug('read return value', p)
  65. return p
  66. }
  67. /**
  68. * Get a list of all DB items.
  69. *
  70. * @return {Promise}
  71. */
  72. list () {
  73. debug('reading data list')
  74. const p = this.model
  75. .find({})
  76. .limit(MAX_RESULTS)
  77. .then(instance => {
  78. debug('read list instance', instance)
  79. return instance
  80. })
  81. // debug('read return value', p)
  82. return p
  83. }
  84. /**
  85. * Update a DB item.
  86. *
  87. * @param {String} id
  88. * @param {String} data
  89. * @return {Promise}
  90. */
  91. update (id, data) {
  92. debug('update data item', id, data)
  93. const filter = {}
  94. filter[this.key] = id
  95. const p = this.model
  96. .findOne(filter)
  97. .then(instance => {
  98. debug('found data instance', instance)
  99. for (let attribute in data) {
  100. if (data.hasOwnProperty(attribute) && attribute !== this.key && attribute !== '_id') {
  101. instance[attribute] = data[attribute]
  102. }
  103. }
  104. return instance.save()
  105. })
  106. .then(instance => {
  107. debug('updated data instance', instance)
  108. return instance
  109. })
  110. // debug('read return value', p)
  111. return p
  112. }
  113. /**
  114. * Delete a DB item.
  115. *
  116. * @param {String} id
  117. * @return {Promise}
  118. */
  119. delete (id) {
  120. debug('delete data item')
  121. const filter = {}
  122. filter[this.key] = id
  123. const p = this.model
  124. .remove(filter)
  125. .then(() => {
  126. return {}
  127. })
  128. // debug('read return value', p)
  129. return p
  130. }
  131. route (parent = undefined) {
  132. const router = new Router({mergeParams: true})
  133. router.get('/', (req, res) => {
  134. this
  135. .list()
  136. .then(data => res.json(data))
  137. .catch(error => res.status(404).send(error))
  138. })
  139. router.post('/', (req, res) => {
  140. this
  141. .create(req.body)
  142. .then(data => res.json(data))
  143. .catch(error => res.status(404).send(error))
  144. })
  145. router.get('/:key', (req, res) => {
  146. this
  147. .read(req.params.key)
  148. .then(data => res.json(data))
  149. .catch(error => res.status(404).send(error))
  150. })
  151. router.put('/:key', (req, res) => {
  152. this
  153. .update(req.params.key, req.body)
  154. .then(data => res.json(data))
  155. .catch(error => res.status(404).send(error))
  156. })
  157. router.delete('/:key', (req, res) => {
  158. this
  159. .delete(req.params.key)
  160. .then(data => res.json(data))
  161. .catch(error => res.status(404).send(error))
  162. })
  163. Object.keys(this.subDocuments).forEach(key => {
  164. router.use(`/:parentKey/${key}`, this.subDocuments[key].route())
  165. })
  166. return router
  167. }
  168. }
  169. export default RESTController