Timi Ajiboye

Simple Sails Validation

Data/model validation is a huge part of any API or application and it's thankfully, very easy to set up in Sails.js.

Model Validations

To illustrate how model level validations work in Sails.js, let us create a new API project and a User model.

sails new validationapp --no-frontend  
sails generate new model User

The first thing one would like to validate for a model attribute is the type of that attribute and sails has five data types built in.
type: 'string', type: 'number', type: 'boolean', type: 'json' and type: 'array'.

Every attribute definition must have one of the above data types. This way, Sails can check and even convert (coerce) request parameters to the required form before persisting.

Validation Rules

There are at least 40 built in attribute validation rules. All of which can be checked out here.

However, in this post, only a few of them would be looked at.
(required, unique, in, email, minLength & maxLength)

Generally, the syntax for implementing validation rules is as shown below.

attributes: {  
  randomAttribute: {
    type: "string",
    validation-rule: value
  }
}

The value could be a string, a number, a boolean value or an array.

Let us add some attributes and accompanying validations to our User model.

/**
 * User.js
 *
 * @description :: Our user model
 */


module.exports = {  
 attributes: {
    email: {
      type: 'email', // checks for a value that is an email address
      required: true, // checks for a value that is not undefined; 
      unique: true, // database constraint (more on that below)
    },

    bloodGroup: {
      type: 'string',
      in: ['A','B','AB','O'], // checks that the value is element of the array
      maxLength: 2 // must have a maximum length of 2 chars
    },

    password: {
      type: 'string',
      minLength: 6, // must have a minimum length of 6 chars
      required: true
    }
  }
};

The above code is pretty easy to understand, but here are a few things to note:

  • The email validation doesn't follow the general syntax for validation that I mentioned above. Older versions of Sails would work with email: true. While newer versions of Sails work ONLY with the above syntax.

  • unique is a special kind of validation in that it doesn't work like the others. It is a universal feature of most databases that ensures that no two records will be allowed with the same value.

Validation Messages

Sails doesn't support custom validation messages out of the box, but someone built a very good library to handle just that. It's called sails-hook-validation.

To use sails-hook-validation in your API:

npm install --save sails-hook-validation

Now you can add validation messages for each attribute's validation rule as such.

  validationMessages: {
    password: {
      required: 'Password is required'
    },

    email: {
      required: 'Email is required',
      email: 'Invalid email',
      unique: 'Email already registered'
    }
  }

In your controller, an overridden Blueprint action or wherever you're creating or updating a model, you can now respond with the validation error messages. These error messages now reside in error.Errors.

    .catch(function (error) {
        if (error.invalidAttributes){
          return res.json(422, {validationErrors: error.Errors});
        }
      }
    )

Controller Validation

Sometimes in a controller action, you may want to validate the parameters passed in a request. It could be that you don't intend to create/update anything or that you want to do some logic before creating/updating.

In any case, it's useful and better to filter and use only the parameters your action needs.

To do this, I use lodash to manipulate arrays. So we need to install that first.

npm install lodash

Then in your controller.

/**
 * UserController
 *
 * @description :: Server-side logic for managing users
 */

var _ = require('lodash');

module.exports = {  
  create: function (req, res) {
    var allowedParameters = [
      "email", "password", "confirmPassword"
    ]

    var data = _.pick(req.body, allowedParameters);

    if (data.password !== data.confirmPassword) {
      return res.json(401, {error: "Password doesn't match"})
    }


    ...
};

In the above example, we use lodash to strip the request parameters of everything we don't want and then perform a simple check to see if the password string matches the confirmation string.

This is just a simple illustration to sort of give an idea as to what can be done when trying to validate request parameters in controller actions.

For more validation information, you should totally check out the Sails.js Documentation.

O dabọ.