A simple, minimalistic object model for nodejs


Okay, so you have a node app backed with some kind of NoSQL schema-less DB such as CouchDB and it all works pretty well,

But hey, even though schema-less is very cool and produces fast results, for small apps it may make sense, but as application code grows bigger and bigger, you will eventually end with low data integrity and things will start to become messy,

So this is what nodejs-model is for, it is a very minimal, extensible model structure for node, it doesn't dictate any DB requirements nor hook into it directly, it's just a plain javascript object with some enhanced capabilities for attributes accessors, validations, tagging and filtering.

Note: If you are aware of Ruby AcitveObject Validations you will probably find some common parts with the validation capability of it, But nodejs-model goes much further, read on :-)

Why use nodejs-model?

If one or more of the bullets below makes sense to you, then you should try nodejs-model.

  • Model attributes: A lightweight javascript model with simple accessors.
  • Attribute validations: define validation rules per defined attribute.
  • Accessibility via tags: Tag attributes with some labels, then allow retrieving/updating only attributes that matches some tags.
  • Events: Events are fired when objects are being created or properties are modified.
  • Converters: Simply hook converters into attributes, for example an encryptor converter may attach to the password attribute of a User model to encrypt the user's password immediately after it is set with new value.


To install nodejs-model, use npm:

$ npm install nodejs-model --save

Basic Usage

This is how it works:

Create a model definition with some validation rules

var model = require('nodejs-model');
//create a new model definition _User_ and define _name_/_password_ attributes 
var User = model("User").attr('name', {
  validations: {
    presence: {
      message: 'Name is required!'
}).attr('password', {
  validations: {
    length: {
      minimum: 5,
      maximum: 20,
      messages: {
        tooShort: 'password is too short!',
        tooLong: 'password is too long!'
  //this tags the accessibility as _private_ 
  tags: ['private']
var u1 = User.create();
//getters are generated automatically'foo');
//prints _foo_ 
//Invoke validations and wait for the validations to fulfill 
u1.validate(function() {
  if u1.isValid {
     //validated, perform business logic 
  } else {
     //validation failed, dump validation errors to the console 
//get object as a plain object, ready for JSON 
//produces: { name: 'foo' } 
//now also with attributes that were tagged with 'private' 
//produces: { name: 'foo' } { password: 'password' } 

Simple as that, your model is enhanced with a validate() method, simply invoke it to validate the model object against the validation rules defined in the schema.

Updating Model Instance

Assuming you have a simple model instance (u1 as defined in the basic example above, you can update it with new data at some point after loading an object from DB / file / JSON / etc:

someObj = {
  name: 'bar',
  password: 'newpassword'
//prints bar 
//NOTE: prints password 

Pay attention that password wasn't updated, this is because when invoking update(object) only public attributes (any attribute that its tags metadata wasnt defined or defined as ['default'] can be updated.

With this specific example, since password is tagged with private, you can update by suppling the private tag to the update() 2nd parameter as:

u1.update(someObj, 'private')
//prints bar 
//NOTE: prints newpassword 


The Presence ensure that an attribute value is not null or empty string, example:

var User = model("User").attr('name', {
  validations: {
    presence: true
  • true - value will be required, default message is set.
  • message - string represents the error message if validator fails.

Example with custom message:

validations: {
  presence: {
    message: 'Name is required!'

Validates rules of the length of a property value.

  • is keyword or number - An exact length
  • array - Will expand to minimum and maximum. First element is the lower bound, second element is the upper bound.
  • allowBlank - Validation is skipped if equal to true and value is empty
  • minimum - Minimum length of the value allowed
  • maximum - Maximum length of the value allowed
  • wrongLength - any string represents the error message if is/number validation fails.
  • tooShort - any string represents the error message if minimum validation fails.
  • tooLong - any string represents the error message if maximum validation fails.
// Examples of is, both are equal, exact 3 length match 
length: 3
length: {is: 3}
//same as above, but empty string is allowed 
length: { is: 3, allowBlank: true } 
//min legnth: 2, max length: 4 
length: [2, 4]
//same as above with custom error messages 
length: { minimum: 2, maximum: 4, messages { tooShort: 'min 3 length!', tooLong: 'max 5 length!' } }

Regexp test validator

  • with - the regular expression to test
  • allowBlank - Validation is skipped if equal to true and value is empty
  • message - any string represents the error message.
// Examples 
format: { with: /^\d*$/, allowBlank: true, message: 'only digits are allowed, or empty string.'  }


nodejs-model supports tags per defined attribute, when new attribute is defined with no tags it will be automatically tagged with the default tag.

Methods such as toJSON(tags_array) or update(updatedObj, tags_array) are accessbility aware when updating or producing model instance output.

You can define tags per attribute by:

User = model("User").attr('name', {
  tags: ['ui', 'registered']
}).attr('password', {
  tags: ['private']
u1 = User.create();'foo');
//prints { age: 55 }, this is because invoking toJSON(), it will only create an object with attributes defined 
as public.
console.log(u1.toJSON(['ui', 'private']));
//prints { name: 'foo', password: 'secret' } 
//* means any property with any tags 
//prints { name: 'foo', password: 'secret', age: 55 } 

Update mehtod someInstance.update(newObj, tags) is also tags-aware as with someInstance.toJSON(tags).

#Initializing Model Instances

It is possible to initialize a model instance by suppliying an init method on the Model level,

Here is an example how to initialize a creation date attribute for a model:

var P = model('Person').attr('name').attr('creation_date');
//will be invoked just after a model is instantiated by P.create() 
P.init = function(instance) {
p1 = P.create();
//prints a date 

#More Info Check wiki pages:


  • amitpaz - Co author, design, tests, etc.


You can contribute in few ways:

  • Just use the module, this is the open source way, right? more usages, more stable and robust the model will be.
  • Star it! :) - if you'r happy with it and find it useful.
  • Code, if you are a coder and would like to contribute code then visit the Development page.


See LICENSE file.