0.1.0 • Public • Published


    The JSON Object Validator

    What is this?

    Straints is JSON object validator that can be used both in node and in the browser. Validation constraints are declaratively defined in a single JSON or YAML file.

    For example:

          { method: "isNull", flip: true }
          { method: "isNull", flip: true }
          { method: "isEmail" }

    With the above (YAML) configuration, executing a Straints validation with a 'create_user' context will ensure that a JSON object has non-null name and email properties and that email is in a valid format.

    In essence, the goal of this project is to provide an easy way to maintain validations used across a web application in a single place.


    • Manage site-wide validations in a single place.
    • Use the same validation configuration in node and in the browser
    • Reusable constraint configurations
    • Reusable validation contexts/schemas
    • Validate nested objects or nested arrays of objects

    Validation tests are not in the scope of this project, and Straints uses validator.js as its validator by default. You can also configure an alternative validator (See Validators section).

    Awesome. How do I get it?


    npm install straints

    or, as a dependency in your project

    npm install straints --save


    bower install straints

    or, as a dependency in your project

    bower install straints --save

    What's the Setup?

    For Node/Express

    var straints = require('straints');
    straints.configure({ ... });

    With no configuration options specified Straints will look for a validation.json file at the root of your project.

    The app.use() call simply adds the Straints instance to the request object. So, in your controllers you can do

    req.straints.validate(req.body, "create_user", function(results)
        if (results.isValid())
            // all validations passed

    To get at the 'global' instance provided through straints.usage, use


    You can also create a new Straints instance if you need to (and pass config options as necessary).

    straints.newInstance({ ... })

    For the Browser

    You will find the js for the browser in the /dist folder.

    <script src="/path/to/straints/straints.min.js"></script>

    Or, if you wish to use the default validator:

    <script src="/path/to/straints/straints-with-validator.min.js"></script>

    Then you can do

        var instance = StraintsFactory.configure({ ... }).getInstance();    

    With no configuration options specified Straints will simply try to request /validation.json.

    Note that The methods described in For Node/Express are available on StraintsFactory.

    How does all this work?

    Configuration Options

    Here are the config options listed with their defaults.

    • load ('[project-root|http-root]/validation.json')
      Specify the validation configuration data here. Here are the options:

      1. (string)
        In a browser this is assumed to be a URL and an XHR GET is attempted. Otherwise, it will assume this is a filename.
      2. (function)
        Must be of the form
      { load: function(callback) { callback(vcdata); } }

      You could also load a file like this

      { load: straints.fileLoader(filename) }

      or a URL like this

      { load: straints.httpLoader(url) }
      1. (object)
        The JSON VC data itself.
    • datatype ('json')
      The type of data being loaded, when load is a string or function ('yaml' or 'json')

    • validator (validator)
      Specify the test method implementation to use here (See Validators section).

    • useStrings (true)
      Set to true to have values converted to strings prior to validation (necessary for validator.js).

    • log (null)
      There is some logging available. Specify the log function here.

    Validation Configuration (VC)

    Let's start with an example:

        name: [ is.notNull ]
        email: [ is.notNull, isEmail ]
        include: person
          position: [ is.basketballPosition ]
            include: person
                include: basketball.player
          name: [ is.notNull ]
          coach: [ is.notNull ]
          players: [ is.notNull ]
      { name: notNull, method: isNull, flip: true }
      { name: basketballPosition, method: isIn, params: [ [ point, guard, forward, water ] ] }

    Note that there are some 'reserved' words in the VC. These are constrain, include, nested, and ____(four underscores). More on these later. The sections below will refer to the example above.


    A 'context' generally defines how a JSON object will be validated. If a path level in the VC has a constrain, include, or nested child, then it can be used as a context.

    In the above our contexts are:

    • person
    • basketball.player

    The context child constrain defines constraints by property name. These constraints will be required if the context is included in the validation session.

    For instance, the 'person' context requires that:

    • 'name' is not null
    • 'email' is not null
    • 'email' is a valid email address

    A context can include other contexts by listing their names in an array or comma-delimited string.

    In the above example, the 'basketball.player' context includes the 'person' context. This means that all of the configuration for the 'person' context now also applies to 'basketball.player' as well.


    If you need to validate an object that includes another object, you can use the nested context area. This works similarly to constrain except that you are specifying new contexts for each property rather than constraints.

    In the above example, a '' object must have a 'coach', as specified by the constrain section of that context. But, we also have

        include: person

    This means that we want to validate the 'coach' property as an object, and so we specify a context for that property.

    The Quadruple Underscore

    While nested alone works well for single objects, what if you want to validate a list of objects?

    Here's the nested 'players' part of the '' context.

            include: basketball.player

    Nest again inside of 'players' to get at the objects in the list. Then you can use the ____ value to apply the context to every element of the array.

    Why the double nesting? Remember that a JS Array is similar to an Object, except that it uses numbers as keys. Thus an array is effectively an object of objects.

    In case you were just wondering, yes, this trick will work on objects of objects as well. It is worth remembering, however, that ____ will apply its contextual validation rules to EVERY object found as a property value of the parent object.


    Constraints can be defined anywhere in the VC, but wherever they appear they must be in an array. There are 3 ways to specify a constraint in the VC.

    1. Constraint Methods

    The simplest way, is to specify the name of a test method in the validator implementation.

      - isEmail

    Note that if the test method requires parameters you will need to build a constraint object instead.

    2. Constraint Object

    This is an actual definition of a constraint. Its unique identifier is the path to it in the VC.

    { name: notNull, method: isNull, flip: true }

    Define constraint objects using these attributes:

    • method (string)
      The method on the validator object that will be called.

    • name (string)
      Identifies the constraint within the list. If not specified, method will be used. If more than one constraint have the same identifier within the same list only the first one loaded will be used.

    • params (array)
      An array of additional parameters to be passed to method on validation (for a single parameter brackets are not needed).

    • flip (boolean)
      Set to true to reverse the boolean value returned by method.

    3. Constraint References

    Lastly, you can include an individual constraint by specifying the path to it in the VC.

          - is.notNull
      { name: notNull, method: isNull, flip: true }

    You can also include an entire array of constraints.

        size: [ sizes ]
      { name: isNotNull, method: isNull, flip: true }
      { method: isIn, params: [ [ small, medium, large ] ] }

    Be aware of potential conflicts here. If a constraint array and a validator method have the same name, the latter will take precedence.

    The Quadruple Underscore (again)

    The ____ can also be used in the realm of constraints.

        - is.notNumeric
        - isEmail
        - isAddress

    Here, the ____ applies its constraints to all properties of the object. This means that, 'email' and 'address' (and EVERY other field) on the object must not be numeric.

    Running a Validation

    straints.validate(target, contexts, complete, validate)
    • target (object)
      The object to be validated

    • contexts (string or array)
      One or more contexts to be validated against

    • complete (function(results))
      Called when validation has completed

      • results (object)
        See Validation Results section below.
    • validate (boolean <= function(property, target, constraint, result))
      Called for every constraint test during the validation session

      • property (string)
        name of the property that was evaludated
      • target (object)
        the object under validation
      • constraint (object)
        validation test that was run
      • result (boolean)
        validation result
      • returns (boolean) the final validation result

    Validation Results

    Here's the rundown on the information available in the validation results object.

    • target
      The JS or JSON object that validation was run against.

    • contexts
      The contexts specified for the validation session.

    • tried
      For each property, the identifiers of the executed constraint tests on the property.

    • failed
      For each property, the identifiers of the failed constraint tests on the property.

    • constraints
      The constraints involved in the validation session indexed by their identifiers.

    • isValid
      A convenience function to determine whether or not all validations passed.


    Straints is bundled with validator.js and uses it by default (i.e., if no validator is provided in the configuration).

    You may use any other validator implementation you wish. Just note that Straints will pass the test value as the first argument to the test method, followed by any parameters.

    What Else?


    Check out the changelog.


    Under construction, but what there is of it can be invoked with

    node test


    For bugs or feature suggestions please use the issue tracker.

    Bugs will be fixed as quickly as possible.




    Happy Validating!


    npm i straints@0.1.0





    Last publish


    • captison