1.6.0 • Published 4 years ago

express-bodychecker v1.6.0

Weekly downloads
1
License
MIT
Repository
-
Last release
4 years ago

express-bodychecker

npm version pipeline status coverage report MIT License

A lightweight npm package for ensuring the body of node express requests is formatted correctly.

Installation

Install dependencies

$ npm install express
$ npm install body-parser

Install this package

Either through cloning with git or by using npm (the recommended way):

$ npm install express-bodychecker

Usage

The express-bodychecker package, is meant to be used as middleware to any express HTTP request where you need to ensure correct content and formatting of the body of the request. E.g.: POST, PUT and DELETE requests.

NOTE: This package will only work when the request body has been exposed on the request with bodyparser.json().

By default, the bodychecker will ensure that the request body only contains the keys with corresponding values defined in the bodytype argument. See Arguments paragraph for details on changing this.

Example

const express = require('express');
const bodyparser = require('body-parser');
const bodychecker = requrie('express-bodychecker');

const app = express();
app.use(bodyparser.json()); // required

// Describe the expected request body
const bodytype = {
    name: String,
    age: {
        type: Number, 
        min: 0,
        max: 120
    }
};

// Define the request, with the bodychecker.check_body method as middleware.
app.put('/', bodychecker.check_body(bodytype), (req, res) => {
    res.status(200)
    res.send('Valid Body');
});

app.listen(8080);

Body type descriptions

The bodychecker.check_body method expects at least one argument, the bodytype argument.

This argument must be a JSON object, that describes the expected body of the HTTP request.

The following bodytype description, describes a body that containes a name key with a string value, an age key with a number value, and a job key of type object. The job object must contain a description key of type string and a salary key of type number.

const bodytype = {
    name: String,
    age: Number,
    job: {
        description: String,
        salary: Number
    }
};

This is pretty much self explanatory.

The type keyword

You can further define a key/value in the body, by using the reserved keyword type in the bodytype description.

Whenever the bodychecker finds a key in the bodytype description that is an object, which in turn has a type key, the object is used as a detailed description of the expected value for the expected key in the body. The detailed description will then used to check that the body key is in compliance with the type, min, max, minlength and/or maxlength values in the detailed description. Note: The min/max values are only used for when the type is set to Number, and minlength and maxlength are used to check the length of body keys with type of String or Array.

const bodytype = {
    name: {
        type: String, // name value must be a String
        minlength: 1, // Minimum length of the name string (inclusive)
        maxlength: 25 // Maximum length of the name string (inclusive)
    },
    age: {
        type: Number, // age value must be a number 
        min: 0, // Minimum value of the age number (inclusive)
        max: 120 // Maximum value of the age number (inclusive)
    },
    intrests: {
        type: Array, // the intrest value must be an array
        element_type: String, // the elements in the intrests array must be of type string
        minlength: 1 // the minimum length of the intrests array (inclusive)
        maxlength: 10 // the maximum length of the intrests array (inclusive)
    },
    children: {
        type: Array, // the children value must be an array
        element_type: { // the children array must contain objects with this content
            name: { 
                type: String, // a childs name must be string
                minlength: 1,
                maxlength: 25
            },
            age: Number, // a childs age must be a number
            intrests: {
                type: Array,
                element_type: String
                minlength: 1,
                maxlength: 10
            }
        }
    }
}

With this bodytype description, this is how the middleware will respond to requests with the following bodies:

A request with the following body will succeed:

req.body = {
    name: "John",
    age: 34, 
    intrest: ['Golf', 'Football', 'Movies'],
    children: [
        {
            name: 'John Jr.',
            age: 9,
            intrests: ['Football', 'Lego']
        }
    ]
}

While this will fail:

req.body = {
    name: "John",
    age: 34, 
    intrest: ['Golf', 'Football', 'Movies'],
    children: [
        {
            name: 'John Jr.',
            age: 9,
            intrests: [] // Will fail because length of child intrests should be between 1 and 10 (inclusive)
        }
    ]
}

This will also fail:

req.body = {
    name: "John",
    age: "34", // Will fail because the age key should be number, but is a string 
    intrest: ['Golf', 'Football', 'Movies'],
    children: [
        {
            name: 'John Jr.',
            age: 9,
            intrests: ['Football', 'Lego']
        }
    ]
}

Arguments

The bodychecker.check_body expects at least one argument, the bodytype argument, as described above.

In addition, the method also accepts another optional argument. The second argument must be a JSON object and contain one or more of the following two key/value pairs.

let second_argument = { // the optional argument
    failurefunction: function(req, res, errors) {
        res.status(400); // bad request
        res.send('There was one or more errors with the received request body');
    },
    checktype: bodychecker.EXPLICIT/bodychecker.REQUIRED
}
bodychecker.check_body(bodytype, second_argument);

The first of these two key/value pairs in the second_argument is a function that is called whenever there are errors found in the request body. Passing the express request and response objects, and an array with descriptions of the errors in the request body. E.g.: The failurefunction key/value must be a function that accepts three arguments (req, res, errors) If no failurefunction key/value pair is supplied to the check_body() method, the bodychecker will send a statuscode of 400 (Bad Request) and an object containing the errors as a response to the request.

The second of the two key/value pairs in the second_argument is the checktype. The checktype is used to describe the "strictness" of the bodychecker middleware. As stated before, the bodychecker middleware will by default deny any request where the request body containes a key that is not present in the bodytype description.

Therefore, by default, a request with the following body and bodytype description will fail:

let bodychecker = require('express-bodychecker');

let bodytype = {
    name: String,
    age: Number
};

/*
    Request will fail if a request to the post "/" route containes the following body:
    req.body = {
        name: "John",
        age: 34, 
        job: "Consultant"
    }
    
    The request will fail because the body containes a key/value pair that is not described by the bodytype description
*/


app.post('/', bodychecker.check_body(bodychecker), (req, res) => {
    res.status(200);
    res.send('Valid body!');
})

If you need the request to succeed in this case, you can pass the second_argument argument to the bodychecker.check_body method, with a value of bodychecker.REQUIRED.

The same request as above will now succeed

let bodychecker = require('express-bodychecker');

let bodytype = {
    name: String,
    age: Number
};

let second_argument = {
    checktype: bodychecker.REQUIRED
}

/*
    Request will succeed if a request to the post "/" route containes the following body:
    req.body = {
        name: "John",
        age: 34, 
        job: "Consultant"
    }
    
    The request would usually have failed because the body containes a key/value pair that is not described by the bodytype description
    But scince we provided the bodychecker.check_body() method with the check_type value of REQUIRED, the request will succeed.
*/


// Request will now succeed when there are key/value pairs in the body that are not described by the bodytype argument
// The request body must still contain all the key/value pairs as described by the bodytype. But now it can also contain other key/value pairs
// The default value for the check_type argument is bodychecker.EXPLICIT
app.post('/', bodychecker.check_body(bodytype, second_argument), (req, res) => {
    res.status(200);
    res.send('Valid body!');
})

Authors

  • Martin Moan

License

This project is licensed under the MIT License - see the LICENSE.md file for details

1.6.0

4 years ago

1.5.1

4 years ago

1.5.0

4 years ago

1.4.0

4 years ago

1.3.0

4 years ago

1.2.0

4 years ago