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

hapi-app-mongo-model

v0.2.5

Published

Lightweight abstraction layer over native MongoDB driver for Hapi App

Downloads

4

Readme

Hapi App Mongo Model

Build Status

Lightweight abstraction layer wrapping Monk api (MongoDB library)

Current version is stable and used in production However it is still work in progress

Rationale

Most popular ODM for MongoDB manipulations from NodeJS is Mongoose. It is build on the top of MongoDB's native driver. It is build with tone of features such us object schemas and validation.

Mongoose is however unnecesary if you would want to reuse Hapi Joi schemas for validation of your model objects or need lower level apis without package overhead.

Hapi-app-mongo-model is provides lightweight abstraction on the top of Monk, which is abstraction over MongoDB native driver.

Core features

  • It can be used stand-alone or registered as Hapi plugin with AppModel.plugin extension
  • It allows to register custom ModelClass-es
  • It exposes mongo collection (monk) methods on custom ModelClasses, such us: find(), findOne(), insert(), etc.
  • It allows to create Models before connection is established (no monk drawbacks)
  • It exposes sugar methods (returning promises) on Model Classes
    • validate(),
    • findAndParse(),
    • findOneAndParse()
    • insertAndParse()
    • forceFind()
  • Helper methods available on modelObject:
    • save(),
    • validate()
    • toJSON()
    • toString()
  • Ease of extensibility of the Helper and DAO methods ( see examples below )

Using Hapi App Mongo Model

This part provides simple example of how to create and use custom models Check example folder for full example code or check test folder for test specs.

Required files

Let's assume User model lives in folder models/user, then required files are:

models/user/
models/user/dao.js
models/user/helpers.js
models/user/index.js
models/user/schema.js

Preparing model source files

File: models/user/index.js

var Model = require('hapi-app-mongo-model'),
	UserModel = Model.register({
		collection: "users",
		path: __dirname
	});
module.exports = UserModel;

File: models/user/dao.js

module.exports = {}

File: models/user/helpers.js

module.exports = {
	fullName : function() {
		return this.fname + ' ' + this.lname;
	}
}

File: models/user/schema.js

var Joi = require('joi'),
	userSchema;
userSchema = {
	fname: Joi.string(),
	lname: JOi.string()
}
module.exports = userSchema;

Connecting to databse

Below examples illustrate connecting to database if you run package outside of Hapi application. For using it as hapi plugin scroll to Using Model as plugin with hapi

Example 1: default connection Model.connect()

In below example Model.connect() is called without any parameters. Model will attempt to Connect to default mongo db url: mongodb://localhost:27017.

var Model = require('hapi-app-mongo-model'),
	connectionConfig = {};

Model
	.connect()
	.then(function (db) {
		// ... CRUD 		
	}, function (error) {
		throw new Error(error);		
	});

Example 2: custom connection Model.connect(config)

Config object takes three parameters:

  • url - mongodb url, fefault value will be used if it is undefined
  • connectionId - identifier is required when there is more than one connection
  • opts - setting object passed to native connect method
var Model = require('hapi-app-mongo-model'),
	connConfig;

connConfig = {
	url: 'mongodb://localhost:27017',	
	connectionID: 'my-awesome-mongo-connection',
	opts: {
		 "db": {
            "native_parser": false
        }
	}
}

Model
	.connect(connConfig)
	.then(function (db) {
		// ... CRUD 		
	}, function (error) {
		throw new Error(error);		
	});

Creating new user object

File: index.js

var User = require('models/user'),
	user;
	
user = new User({
	fname: 'John',
	fname: 'Smith'
});

// call build-in helper
console.log(user.toJSON());

// call local helper
console.log(user.fullName());

User Reference

Using Model as plugin with hapi Model.plugin

done, there are no tests yet

var Hapi = require('hapi'),
	server = new Hapi.Server();

server.connection({ port: 3000 });
server.register({
	"url": "mongodb://localhost:27017/test",
	"opts": {
		"db": {
			"native_parser": false
		}
	}
}, function (error) {
	//...
	server.start();
});

Shared connection Model.db

Model.connect(settings) creates connection that can be accessed via:

  • Model.db
  • YourModel.db
  • yourObject.db

Schamas

Models are required to have schema.js file which exports model object schema ready for validation with Joi.validate().

Simply follow Joi docs to create one. Check example code to see it in action.

Indexes

Uses monk indexing exposed on collection.

Custom Model namespaced methods

Methods exposed on the level of Custom Model are equivalent to collection methods, and so for example call to below method update():

var Model = require('hapi-app-mongo-model');
Model.db.collection[{collection-name}].update( ... )

can be conviniently simplified to:

var UserModel = require('/path/to/user-model');
UserModel.update( ... )

Creating Model Classes Model.register()

Method used to generate Custom Model Class takes config object with three parameters:

  • collection - name of mongoDB collection
  • path - path to Custom Model directory directory with schema, dao and helpers files.

Example Model Class generation:

var Model = require('hapi-app-mongo-model')
	modelTaskConfig;

modelTaskConfig = {
    collection: "tasks",
    path: __dirname
}

module.exports = Model.generate(modelTaskConfig);

Find method Model.find()

Convenience method

FindOne method Model.findOne()

Convenience method

ObjectId via Model.ObjectId() and Model.ObjectID()

Convenience method

DAO helpers

Createing object via new ModelClass(collectionName, [object])

Createing object via ModelClass.create(collectionName, [object])

Convenience method for new ModelClass(collectionName, [object])

status: implemented but no tests

Find <ModelClass>.find()

Convenience method

FindOne <ModelClass>.findOne()

Convenience method

Custom DAO helpers

todo: missing test to confirm prototypical inheritance with parent class method exposed via _super that will allow to override them in models/model/dao.js

Model Object helpers

Save <modelObject>.save()

Convenience method returns promise

Validate <modelObject>.validate()

Convenience method returns promise

validate() is async method and returns a promise. It can be handled in one of two ways as shown below.

Method 1: promise.then(onSuccess, onError)

user.validate()
	.then(function onSuccess(data) {	    
	    //.. do something with data 
	}, function onError(error) {
	    //.. do something with error 
	});

Method 2: promise.onFulfill(onSuccess).onReject(onError)

user.validate()
	.then(function onSuccess(data) {	    
	    //.. do something with data 
	}, function onError(error) {
	    //.. do something with error 
	});

Resources

BIG THANK YOU TO ALL THE AUTHORS FOR DEVELOPING THOSE GREAT PACKAGES, FOR MAKING CODING EASIER, FASTER AND MORE FUN!

CHEEERIO!!!

Used HapiJs package

  • Hapi - A rich framework for building applications and services
  • Hoek - Utility methods for the hapi ecosystem
  • Good - Hapi process monitoring
  • Boom - HTTP-friendly error objects
  • Joi - Object schema description language and validator for JavaScript objects.

Used packages