0.5.5 • Published 8 years ago

@rill/mongoose v0.5.5

Weekly downloads
1
License
MIT
Repository
github
Last release
8 years ago

Mongoose REST api generator for Rill with flexible defaults and easy overrides.

Installation

npm install @rill/mongoose

Features

  • Feature packed default routes.
  • Automatically sanitize inputs/outputs (query/body) for hidden fields.
  • Easily override or add to default middleware.
  • Uses lean / optimized queries.
  • Good query api with many features including populate, select, limit, skip and sort.

Example Setup

const Rill = require('rill')
const resource = require('@rill/mongoose')

const app = Rill()

// Create any mongoose model.
const User = mongoose.model('user', {
  name: { type: String, required: true },
  hidden: { type: String, hidden: true } // Any fields marked as hidden will not be accessible through any part of the api.
})

// Setup a "GET/find" request for the user route using the optimized default middleware.
app.use(resource(User, { find: 'default' }))

Example Consumption

// Consume using WHATWG Fetch api.
fetch('/user?$select=name&$limit=10')
  .then(res => res.json())
  .then(users => {
    /**
     * Returns up to 10 users
     * with only the `_id` and `name` fields selected.
     */
  })

API

  • resource(path: String, Model: Mongoose.model, methods: Object) : Creates a REST api for the provided model with the configured methods.
// Choose which methods to enable.
app.use(resource(UserModel, {
  // `GET` requests.
  find: 'default',
  // `GET/:id` requests.
  findById: 'default',
  // `POST` requests.
  create: 'default',
  // `PUT|PATCH/:id` requests.
  save: 'default',
  // `DELETE/:id` requests.
  remove: 'default'
}))

// Add more middleware to methods (while optionally still using defaults).
app.use(resource(PermissionsModel, {
  // Runs `restrictAdmin` middleware before the default middleware.
  find: [restrictAdmin, 'default']
}))

// Also override the default path for the handlers.
app.use(resource('/somepath', SomeOtherModel, ...))

Query API

The querystring is sanitized then passed into Model.find allowing for any sort of Mongoose style query in a safe way.

All queries will also add an X-Total-Count http header which is the total number of documents found ignoring $skip and $limit, useful for pagination.

fetch('/user?age=10&loggedIn[$gt]=' + new Date(2015)) // Find all users who are age 10 and have logged in after 2015.

Special Query Operators

There are some special operators to make working with the api more flexible.

  • $skip : skip a number of results.
fetch('/user?$skip=10') // Skip the first 10 users.
  • $limit : limit the number of results.
fetch('/user?$limit=10') // Get at most 10 users.
  • $sort : sort the results.
fetch('/user?$sort=name email') // Sort users by name, then email.
fetch('/user?$sort=-name') // Sort users by name in descending order.
  • $select : limit the fields in the results.
fetch('/user?$select=name email') // Get all users, but only with their name and email and _id.
fetch('/user?$select=name email -_id') // Same query, but omit _id this time.
  • $populate : populate related fields for the Model.
fetch('/user?$populate=posts friends') // Will `populate` the `posts` and `friends` field if they are not hidden on the api for all users.

// populate specific fields. (wrap fields in "[]")
fetch('/user?$populate=posts[title date]') // `populate` posts for each user but only include the post title and date.

// nested populate. (separate nested populate with ":")
fetch('/user?$populate=posts[author]:author[name]') // `populate` all `posts`, with only the `author` - then populate all posts authors with only their `name`.

Creating documents

You can POST to the api to create new documents for the Model.

// Create a new user.
fetch('/user', {
  method: 'POST',
  body: JSON.stringify({
    name: 'Cool Api Dude',
    hidden: 'Test' // Hidden fields and extra fields will be ignored.
  })
})
  .then(res => res.json())
  .then(user => {
    // New user created!
    console.log(user._id)
  })

Updating documents

You can use PUT/:id to replace an existing document and PATCH/:id to update a document.

// Overwrite an existing user.
fetch('/user/000000000000000000000000', {
  method: 'PUT',
  body: JSON.stringify({
    // Completely overwrite all fields.
    name: 'Cool Api Dude'
  })
})
  .then(res => res.json())
  .then(user => {
    // Updated user!
    console.log(user._id)
  })

// Update an existing user.
fetch('/user/000000000000000000000000', {
  method: 'PATCH',
  body: JSON.stringify({
    // Will only update `name` leaving other fields as is.
    name: 'Cool Api Dude'
  })
})
  .then(res => res.json())
  .then(user => {
    // Updated user!
    console.log(user._id)
  })

Removing documents

You can use DELETE/:id to permanently remove a document.

// Remove an existing user.
fetch('/user/000000000000000000000000', { method: 'DELETE' })
  .then(res => res.json())
  .then(user => {
    // I was deleted :(.
    console.log(user._id)
  })

Validation

Mongoose validation is also automatically handled for POST|PUT|PATCH requests.

fetch('/user', {
  method: 'POST',
  body: JSON.stringify({
    name: null // This will fail because `name` is required.
  })
})
  .then(res => {
    // Automatically sets status and an error message header.
    res.status //-> 400
    res.headers.get('X-Error-Message') //-> 'Path `name` is required.'
    return res.json()
  })
  .then(({ error }) => {
    error.name === 'ValidationError'// Also sends the validation error as JSON.
  })

Contributions

Please use npm test for tests and feel free to create a PR!

0.5.5

8 years ago

0.5.4

8 years ago

0.5.3

9 years ago

0.5.2

9 years ago

0.5.1

9 years ago

0.5.0

9 years ago

0.4.1

9 years ago

0.4.0

9 years ago

0.3.5

9 years ago

0.3.4

9 years ago

0.3.2

9 years ago

0.3.1

9 years ago

0.3.0

10 years ago

0.2.4

10 years ago

0.2.3

10 years ago

0.2.2

10 years ago

0.2.1

10 years ago

0.2.0

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago