{"id":16473226,"url":"https://github.com/saintedlama/restify-mongoose","last_synced_at":"2025-04-06T17:12:21.136Z","repository":{"id":13495307,"uuid":"16185927","full_name":"saintedlama/restify-mongoose","owner":"saintedlama","description":"Restify-Mongoose provides a resource abstraction to expose mongoose models as REST resources.","archived":false,"fork":false,"pushed_at":"2024-09-06T07:39:39.000Z","size":1869,"stargazers_count":110,"open_issues_count":50,"forks_count":34,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-12T12:25:40.853Z","etag":null,"topics":["javascript","mongoose","rest-api","restify"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saintedlama.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-01-23T21:15:54.000Z","updated_at":"2023-07-17T16:53:35.000Z","dependencies_parsed_at":"2024-06-18T17:08:10.437Z","dependency_job_id":"f1161471-907b-4f21-afad-b5b342ac6a7b","html_url":"https://github.com/saintedlama/restify-mongoose","commit_stats":{"total_commits":161,"total_committers":15,"mean_commits":"10.733333333333333","dds":0.5590062111801242,"last_synced_commit":"1c01c5b14770326e901f0b8096b67908ecc3527d"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saintedlama%2Frestify-mongoose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saintedlama%2Frestify-mongoose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saintedlama%2Frestify-mongoose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saintedlama%2Frestify-mongoose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saintedlama","download_url":"https://codeload.github.com/saintedlama/restify-mongoose/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247517915,"owners_count":20951719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mongoose","rest-api","restify"],"created_at":"2024-10-11T12:25:53.154Z","updated_at":"2025-04-06T17:12:21.096Z","avatar_url":"https://github.com/saintedlama.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Restify-Mongoose\n[![NPM](https://nodei.co/npm/restify-mongoose.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://nodei.co/npm/restify-mongoose/)\n\n[![Build Status](https://travis-ci.org/saintedlama/restify-mongoose.png?branch=master)](https://travis-ci.org/saintedlama/restify-mongoose)\n[![Coverage Status](https://coveralls.io/repos/saintedlama/restify-mongoose/badge.png?branch=master)](https://coveralls.io/r/saintedlama/restify-mongoose?branch=master)\n[![Dependencies Status](https://david-dm.org/saintedlama/restify-mongoose.svg)](https://david-dm.org/saintedlama/restify-mongoose)\n[![devDependency Status](https://david-dm.org/saintedlama/restify-mongoose/dev-status.svg)](https://david-dm.org/saintedlama/restify-mongoose#info=devDependencies)\n\nRestify-Mongoose provides a resource abstraction for [restify](http://mcavage.me/node-restify/) to expose mongoose models as REST resources.\n\n## Getting started\nFirst you'll need to install restify-mongoose via npm\n\n    npm install restify-mongoose\n\nSecond step is to wire up mongoose and restify using restify-mongoose\n\n```javascript\nvar restify = require('restify');\nvar restifyMongoose = require('restify-mongoose');\nvar mongoose = require('mongoose');\n\nvar server = restify.createServer({\n    name: 'restify.mongoose.examples.notes',\n    version: '1.0.0'\n});\n\nserver.use(restify.plugins.acceptParser(server.acceptable));\nserver.use(restify.plugins.queryParser());\nserver.use(restify.plugins.bodyParser());\n\n// Create a simple mongoose model 'Note'\nvar NoteSchema = new mongoose.Schema({\n    title : { type : String, required : true },\n    date : { type : Date, required : true },\n    tags : [String],\n    content : { type: String }\n});\n\nvar Note = mongoose.model('notes', NoteSchema);\n\n// Now create a restify-mongoose resource from 'Note' mongoose model\nvar notes = restifyMongoose(Note);\n\n// Serve resource notes with fine grained mapping control\nserver.get('/notes', notes.query());\nserver.get('/notes/:id', notes.detail());\nserver.post('/notes', notes.insert());\nserver.patch('/notes/:id', notes.update());\nserver.del('/notes/:id', notes.remove());\n\nserver.listen(3000, function () {\n    console.log('%s listening at %s', server.name, server.url);\n});\n```\n\n# Resources\nTo map resources or resource functionality to restify REST endpoints/routes restify-mongoose offers\ntwo approaches:\n\n* 'fine grained mapping' control via list, detail, new, update and delete functions\n* 'quick mapping' via serve method\n\n__Fine grained mapping__\nIn the above getting started example we used fine grained mapping control. Restify-mongoose defines the functions `query`,\n`detail`, `insert`, `update` and `remove` that return restify route handlers and can be used like this:\n\n```javascript\n // Serve resource notes with fine grained mapping control\n server.get('/notes', notes.query());\n server.get('/notes/:id', notes.detail());\n server.post('/notes', notes.insert());\n server.patch('/notes/:id', notes.update());\n server.del('/notes/:id', notes.remove());\n```\n\nFor every ´id´ dependent function the restify route has to define a `:id` placeholder to allow restify-mongoose to access\nid parameters. Id dependent functions are `detail`, `update` and `delete`.\n\n__Query String__\n\nSetting a `queryString` will make restify-mongoose use the string as the field name to conduct its searches in the `detail` `update` \u0026 `remove` functions.\nIf not set it will use the default behavior of using mongos `_id` field.\n\n```javascript\n// Now create a restify-mongoose resource from 'Note' mongoose model and set queryString to 'myField'\nvar notes = restifyMongoose(Note, {queryString: 'myField'});\n\n// these functions will now conduct searches with the field 'myField'. (defaults to '_id')\nserver.get('/notes/:id', notes.detail());\nserver.patch('/notes/:id', notes.update());\nserver.del('/notes/:id', notes.remove());\n```\n\n__Quick mapping__\n\n```javascript\n// Serve resource notes with quick mapping\nrestifyMongoose(models.Note).serve('/api/notes', server);\n```\n\nMaps urls\n\n* GET '/api/notes' to `query` function\n* GET '/api/notes/:id' to `detail` function\n* POST '/api/notes' to `insert` function\n* DELETE '/api/notes/:id' to `remove` function\n* PATCH '/api/notes/:id' to `update` function\n\nYou can also pass an options object to the `serve` method to attach handlers before and after the request.\nFor example, to use [restify-jwt](https://github.com/auth0/express-jwt):\n\n```javascript\n// Serve resource notes with quick mapping with JWT auth\nrestifyMongoose(models.Note).serve('/api/notes', server, { before: jwt({secret: 'some-secret'}) } );\n```\n\n## Queries\nQuery parameters are passed by query string parameter __q__.\n\nQuery parameters are parsed as JSON objects and passed to [mongoose where query function](http://mongoosejs.com/docs/api.html#query_Query-where).\n\nTo filter a notes resource by title to match term \"first\" append the __q__ query parameter to the URL:\n\n    http://localhost:3000/notes?q={\"title\":\"first\"}\n\n## Paginate\nRequests that return multiple items in `query` will be paginated to 100 items by default. You can set the `pageSize`\n(number min=1) by adding it to the options.\n\n```javascript\nvar options = {\n\tpageSize: 2\n};\n\nvar notes = restifyMongoose(Note, options);\n```\n\nor as query string parameter `pageSize` (which will have the presedence)\n\n    http://localhost:3000/notes?pageSize=2\n\n\nYou can specify further pages with the __p__ parameter and a page number.\n\n    http://localhost:3000/notes?p=1\n\nAn additional restriction to page sizes can be made with `maxPageSize` option (default value is 100) that defines the\nmaximum allowed page size to avoid unbound queries.\n\n### Link Header\nThe pagination info is included in [the Link header](http://tools.ietf.org/html/rfc5988). It is important to follow\nthese Link header values instead of constructing your own URLs.\n\n    link:\n    \u003chttp://example.com/notes?p=0\u003e; rel=\"first\",\n    \u003chttp://example.com/notes?p=1\u003e; rel=\"prev\",\n    \u003chttp://example.com/notes/?p=3\u003e; rel=\"next\",\n    \u003chttp://example.com/notes/?p=4\u003e; rel=\"last\"\n\n_Linebreak is included for readability._\n\nYou can set the `baseUrl` by adding it to the options.\n\n```javascript\nvar options = {\n\tbaseUrl: 'http://example.com'\n};\n```\n\nThe possible `rel` values are:\n\n* ***next*** - Shows the URL of the immediate next page of results.\n* ***last*** - Shows the URL of the last page of results.\n* ***first*** - Shows the URL of the first page of results.\n* ***prev*** - Shows the URL of the immediate previous page of results.\n\n### Total Count Header\nThe total number of results/resources returned in `query` is sent in the `X-Total-Count Header` and is not affected by\npagination (setting `pageSize` and __p__ parameter). It does take in account filter and query parameter ( __q__ ).\n\n## Sort\nSort parameters are passed by query string parameter __sort__.\n\nSort parameters can be separated by comma or space. They will be passed directly to [mongoose sort query function](http://mongoosejs.com/docs/api.html#query_Query-sort).\n\nTo sort a notes resource by title descending append the __sort__ query parameter to the URL:\n\n    http://localhost:3000/notes?sort=-title\n\nYou can also define a default sort in the options object. This option will by ignored if a __sort__ query parameter exists.\n\nUsing in the constructor:\n```javascript\nvar notes = restifyMongoose(Note, {sort: '-title'});\nnotes.serve('/notes', restifyServer);\n```\n\nUsing for query or detail methods:\n```javascript\nvar notes = restifyMongoose(Note);\nnote.query({sort: '-title'});\n\n## Select Fields\nTo restrict selected columns you can pass a query string parameter __select__.\n\nSelect fields can be separated by comma or space. They will be passed to [mongoose select query function](http://mongoosejs.com/docs/api.html#query_Query-select).\n\nTo select only title and date the fields of a notes resource append the __select__ query parameter to the URL:\n\n    http://localhost:3000/notes?select=title,date\n\nYou can also define select fields in the options object. This will make the the __select__ query parameter be ignored.\n\nUsing in the constructor:\n```javascript\nvar notes = restifyMongoose(Note, {select: 'title'});\nnotes.serve('/notes', restifyServer);\n```\n\nUsing for query or detail methods:\n```javascript\nvar notes = restifyMongoose(Note);\nnote.detail({select: 'title,date,tags'});\nnote.query({select: 'title date'});\n```\n\n## Filter\nResults can be filtered with a function, which is set in the options object of the constructor or on the `query` and `detail` function.\n\nThe function takes two parameters: the request object and the response object. The return value of the function is a query that is passed directly to the [mongoose where query function](http://mongoosejs.com/docs/api.html#query_Query-where).\n\nFor instance, you can use a filter to display only results for a particular user:\n\n```javascript\nvar filterUser = function(req, res) {\n  return {user: req.user};\n}\n\nvar notes = restifyMongoose(Note, {filter: filterUser});\n```\n\n## Projection\n\nA projection is a function, used by the `query` and `detail` operations, which takes the request object, the result model, and a callback. This function should invoke the callback exactly once. This callback takes an error and a model item as it's two parameters. Use `null` for the error is there is no error.\n\nFor instance, the default detail and list projections are as follows:\n\n```javascript\nfunction (req, item, cb) {\n  cb(null, item);\n};\n```\n\nA projection is useful if you need to manipulate the result item before returning it in the response. For instance, you may not want to return the passwordHash for a User data model.\n\n```javascript\n// If this is the schema\nvar UserSchema = new Schema({\n  username: String,\n  email: String,\n  passwordHash: String\n});\n\n// This is a projection translating _id to id and not including passwordHash\nvar userProjection = function(req, item, cb) {\n  var user = {\n    id: item._id,\n    username: item.username,\n    email: item.email\n  };\n  cb(null, user);\n};\n```\n\nProjection functions are specified in the options for the resitfy-mongoose contructor, the query function, or the detail function.\n\nFor the construtor, the options are `listProjection` and `detailProjection`\n\n```javascript\nvar users = restifyMongoose(User, {listProjection: userProjection, detailProjection: userProjection});\nusers.serve('/users', restifyServer);\n```\n\nFor both query and detail, the option is `projection`\nvar users = restifyMongoose(User);\n\n```javascript\nusers.detail({projection: userProjection});\nusers.query({projection: userProjection});\n```\n## Output format\n\nThe output format can be changed to a more compatible one with the [json-api](http://jsonapi.org/format/) standard to use the API with frameworks like Ember.\n\n```javascript\nvar users = restifyMongoose(User, {outputFormat: 'json-api'});\nusers.serve('/users', restifyServer);\n``\nAlso you can specify a custom model name like this:\n\n```javascript\nvar users = restifyMongoose(User, {outputFormat: 'json-api', modelName: 'admins'});\nusers.serve('/users', restifyServer);\n```\n\n## Populating referenced documents\n\nThe returned results can use mongoose's \"populate\" query modifier to populated referenced documents within models.\n\nReferenced documents can be populated in three ways:\n\n#### query parameter\nAdding `populate=[referenced_field]` to the query string will populate the `referenced_field`, if it exists.\n\n#### Resource option\n```javascript\n// e.g.\nvar notes = restifyMongoose(Note, {populate: 'author'});\n```\n\n#### query / detail method options\n```javascript\n// e.g.\nserver.get('/notes', notes.query({populate: 'author'}))\nserver.get('/notes/:id', notes.detail({populate: 'author'}))\n```\n\n### Populating multiple fields\nMultiple referenced documents can be populated by using a comma-delimited list of the desired fields in any of the three methods above.\n```javascript\n// e.g.\nvar notes = restifyMongoose(Note, {populate: 'author,contributors'});\n```\n\n# Contribute\nContribution welcome! Read the [contribution guideline](contributing.md) first.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaintedlama%2Frestify-mongoose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaintedlama%2Frestify-mongoose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaintedlama%2Frestify-mongoose/lists"}