npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@teacode/feathers-mongoose-teacode

v7.0.0

Published

A Feathers service adapter for the Mongoose ORM

Downloads

5

Readme

@teacode/feathers-mongoose-teacode

A Feathers database adapter for Mongoose, an object modeling tool for MongoDB.

Important: It's forked from [feather-mongoose] (https://github.com/feathersjs-ecosystem/feathers-mongoose) changing code to trigger pre save and pre remove hooks in mongoose.

$ npm install --save mongoose @teacode/feathers-mongoose-teacode

Important: feathers-mongoose implements the Feathers Common database adapter API and querying syntax.

This adapter also requires a running MongoDB database server.

API

service(options)

Returns a new service instance initialized with the given options. Model has to be a Mongoose model. See the Mongoose Guide for more information on defining your model.

const mongoose = require('mongoose');
const service = require('feathers-mongoose');

// A module that exports your Mongoose model
const Model = require('./models/message');

// Make Mongoose use the ES6 promise
mongoose.Promise = global.Promise;

// Connect to a local database called `feathers`
mongoose.connect('mongodb://localhost:27017/feathers');

app.use('/messages', service({ Model }));
app.use('/messages', service({ Model, lean, id, events, paginate }));

Options:

  • Model (required) - The Mongoose model definition
  • lean (optional, default: true) - Runs queries faster by returning plain objects instead of Mongoose models.
  • id (optional, default: '_id') - The name of the id field property.
  • events (optional) - A list of custom service events sent by this service
  • paginate (optional) - A pagination object containing a default and max page size
  • discriminators (optional) - A list of mongoose models that inherit from Model.

Important: To avoid odd error handling behaviour, always set mongoose.Promise = global.Promise. If not available already, Feathers comes with a polyfill for native Promises.

Important: When setting lean to false, Mongoose models will be returned which can not be modified unless they are converted to a regular JavaScript object via toObject.

Note: You can get access to the Mongoose model via this.Model inside a hook and use it as usual. See the Mongoose Guide for more information on defining your model.

params.mongoose

When making a service method call, params can contain a mongoose property which allows you to modify the options used to run the Mongoose query. Normally, this will be set in a before hook:

app.service('messages').hooks({
  before: {
    patch(context) {
      // Set some additional Mongoose options
      // The adapter tries to use sane defaults
      // but they can always be changed here
      context.params.mongoose = {
        runValidators: true,
        setDefaultsOnInsert: true
      }
    }
  }
});

The mongoose property is also useful for performing upserts on a patch request. "Upserts" do an update if a matching record is found, or insert a record if there's no existing match. The following example will create a document that matches the data, or if there's already a record that matches the params.query, that record will be updated.

const data = { address: '123', identifier: 'my-identifier' }
const params = {
  query: { address: '123' },
  mongoose: { upsert: true }
}
app.service('address-meta').patch(null, data, params)

Example

Here's a complete example of a Feathers server with a messages Mongoose service.

$ npm install @feathersjs/feathers @feathersjs/errors @feathersjs/express mongoose feathers-mongoose

In message-model.js:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const MessageSchema = new Schema({
  text: {
    type: String,
    required: true
  }
});
const Model = mongoose.model('Message', MessageSchema);

module.exports = Model;

Then in app.js:

const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');

const mongoose = require('mongoose');
const service = require('feathers-mongoose');

const Model = require('./message-model');

mongoose.Promise = global.Promise;

// Connect to your MongoDB instance(s)
mongoose.connect('mongodb://localhost:27017/feathers');

// Create an Express compatible Feathers application instance.
const app = express(feathers());

// Turn on JSON parser for REST services
app.use(express.json());
// Turn on URL-encoded parser for REST services
app.use(express.urlencoded({extended: true}));
// Enable REST services
app.configure(express.rest());
// Enable Socket.io services
app.configure(socketio());
// Connect to the db, create and register a Feathers service.
app.use('/messages', service({
  Model,
  lean: true, // set to false if you want Mongoose documents returned
  paginate: {
    default: 2,
    max: 4
  }
}));
app.use(express.errorHandler());

// Create a dummy Message
app.service('messages').create({
  text: 'Message created on server'
}).then(function(message) {
  console.log('Created message', message);
});

// Start the server.
const port = 3030;
app.listen(port, () => {
    console.log(`Feathers server listening on port ${port}`);
});

You can run this example by using node app and go to localhost:3030/messages.

Querying, Validation

Mongoose by default gives you the ability to add validations at the model level. Using an error handler like the one that comes with Feathers your validation errors will be formatted nicely right out of the box!

For more information on querying and validation refer to the Mongoose documentation.

$populate

For Mongoose, the special $populate query parameter can be used to allow Mongoose query population.

app.service('posts').find({
  query: { $populate: 'user' }
});

Discriminators (Inheritance)

Instead of strict inheritance, Mongoose uses discriminators as their schema inheritance model. To use them, pass in a discriminatorKey option to your schema object and use Model.discriminator('modelName', schema) instead of mongoose.model()

Feathers comes with full support for mongoose discriminators, allowing for automatic fetching of inherited types. A typical use case might look like:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Post = require('./post');
var feathers = require('@feathersjs/feathers');
var app = feathers();
var service = require('feathers-mongoose');

// Discriminator key, we'll use this later to refer to all text posts
var options = {
  discriminatorKey: '_type'
};

var TextPostSchema = new Schema({
  text: { type: String, default: null }
}, options);

// Note the use of `Post.discriminator` rather than `mongoose.discriminator`.
var TextPost = Post.discriminator('text', TextPostSchema);

// Using the discriminators option, let feathers know about any inherited models you may have
// for that service
app.use('/posts', service({
  Model: Post,
  discriminators: [TextPost]
}))

Without support for discriminators, when you perform a .get on the posts service, you'd only get back Post models, not TextPost models. Now in your query, you can specify a value for your discriminatorKey:

{
  _type: 'text'
}

and Feathers will automatically swap in the correct model and execute the query it instead of its parent model.

License

MIT

Authors