{"action":"created","issue":{"url":"https://api.github.com/repos/feathersjs/feathers/issues/272","repository_url":"https://api.github.com/repos/feathersjs/feathers","labels_url":"https://api.github.com/repos/feathersjs/feathers/issues/272/labels{/name}","comments_url":"https://api.github.com/repos/feathersjs/feathers/issues/272/comments","events_url":"https://api.github.com/repos/feathersjs/feathers/issues/272/events","html_url":"https://github.com/feathersjs/feathers/issues/272","id":142224035,"number":272,"title":"Services API Enhancement","user":{"login":"hnordt","id":1625399,"avatar_url":"https://avatars.githubusercontent.com/u/1625399?v=3","gravatar_id":"","url":"https://api.github.com/users/hnordt","html_url":"https://github.com/hnordt","followers_url":"https://api.github.com/users/hnordt/followers","following_url":"https://api.github.com/users/hnordt/following{/other_user}","gists_url":"https://api.github.com/users/hnordt/gists{/gist_id}","starred_url":"https://api.github.com/users/hnordt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hnordt/subscriptions","organizations_url":"https://api.github.com/users/hnordt/orgs","repos_url":"https://api.github.com/users/hnordt/repos","events_url":"https://api.github.com/users/hnordt/events{/privacy}","received_events_url":"https://api.github.com/users/hnordt/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/feathersjs/feathers/labels/Discussion","name":"Discussion","color":"fad8c7"},{"url":"https://api.github.com/repos/feathersjs/feathers/labels/Proposal","name":"Proposal","color":"F4A177"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-03-21T00:08:00Z","updated_at":"2016-03-21T21:15:43Z","closed_at":null,"body":"Here is my suggestion for enhancing Services API:\r\n\r\n```js\r\n// feathers-service package\r\n\r\nclass Service {\r\n  constructor(db, options) {\r\n    if (!db) {\r\n      throw new Error('db is required')\r\n    }\r\n    this.db = db\r\n    this.id = options.id || '_id'\r\n    this.beforeCreate = options.beforeCreate\r\n    // other hooks\r\n    this.paginate = options.paginate || {}\r\n  }\r\n  // ...\r\n}\r\n\r\n// feathers-nedb package\r\n\r\nimport Service from 'feathers-service'\r\nimport NeDB from 'nedb'\r\n\r\nclass NeDBService extends Service {\r\n  constructor(options) {\r\n    if (!options.filename) {\r\n      throw new Error('filename is required')\r\n    }\r\n    const db = new NeDB({\r\n      filename: options.filename,\r\n      autoload: true\r\n    })\r\n    super(db, options)\r\n  }\r\n  find() {\r\n    // ...\r\n  }\r\n  // ...\r\n}\r\n\r\n// usage\r\n\r\nimport NeDBService from 'feathers-nedb'\r\n\r\nconst messageService = new NeDBService({\r\n  filename: '/some/path/messages.db',\r\n  beforeCreate(data) { // pure function :)\r\n    return { ...data, createdAt: new Date() }\r\n  },\r\n  validate({ author, text }) { // \"Syntax\" sugar, inside Service it'll be called by create(), update(), patch() and errors wrapped in errors.BadRequest()\r\n    const errors = []\r\n    if (!author || !author.name) {\r\n      errors.push({\r\n        {\r\n          path: 'author.name',\r\n          message: 'Author Name is required'\r\n        }\r\n      })\r\n    }\r\n    if (!text) {\r\n      errors.push({\r\n        {\r\n          path: 'text',\r\n          message: 'Text is required'\r\n        }\r\n      })\r\n    }\r\n    return errors\r\n  }\r\n})\r\n```\r\n\r\nI would like to help writing the implementation if @ekryski and @daffl likes it."},"comment":{"url":"https://api.github.com/repos/feathersjs/feathers/issues/comments/199490389","html_url":"https://github.com/feathersjs/feathers/issues/272#issuecomment-199490389","issue_url":"https://api.github.com/repos/feathersjs/feathers/issues/272","id":199490389,"user":{"login":"ekryski","id":599019,"avatar_url":"https://avatars.githubusercontent.com/u/599019?v=3","gravatar_id":"","url":"https://api.github.com/users/ekryski","html_url":"https://github.com/ekryski","followers_url":"https://api.github.com/users/ekryski/followers","following_url":"https://api.github.com/users/ekryski/following{/other_user}","gists_url":"https://api.github.com/users/ekryski/gists{/gist_id}","starred_url":"https://api.github.com/users/ekryski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekryski/subscriptions","organizations_url":"https://api.github.com/users/ekryski/orgs","repos_url":"https://api.github.com/users/ekryski/repos","events_url":"https://api.github.com/users/ekryski/events{/privacy}","received_events_url":"https://api.github.com/users/ekryski/received_events","type":"User","site_admin":false},"created_at":"2016-03-21T21:15:43Z","updated_at":"2016-03-21T21:15:43Z","body":"You can already `extend` services to add custom functionality like your `validate` and `beforeCreate` methods (I just realized that's not in the docs).\r\n\r\nHowever, I think the better solution is to use [hooks](http://docs.feathersjs.com/hooks/readme.html) for what you want. This is really what they were made for. You might want to look at:\r\n\r\n- https://github.com/kulakowka/feathers-transform-hook\r\n- https://github.com/kulakowka/feathers-validate-hook\r\n\r\nIMHO this actually makes the services a bit more bloated than they need to be and makes them more ORM-like."}}