express-superstruct

An express validation middleware that uses superstruct

Usage no npm install needed!

<script type="module">
  import expressSuperstruct from 'https://cdn.skypack.dev/express-superstruct';
</script>

README

express-superstruct

An express validation middleware that uses superstruct

  • Replaces the incoming req.body, req.query, with the validated result, original values are kept inreq._body/req._query
  • Express error middleware will be executed upon validation error

Install

npm install express-superstruct

Usage

const { validate } = require('express-superstruct');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// without req.body/req.query filled, nothing will be validated.
app.use(bodyParser.json());

app.post(
    '/item', 
    validate({ title: 'string', stock: 'number' }),
    (req, res, next) => {
        console.log(req.body.title); // I'm a string 100%
        console.log(req.body.stock); // I'm a number 100%
        res.end('ok');
    }
);

app.get(
    '/item', 
    // Number does not work for GET, since everything is a string/array
    // You may need a custom numeric type. (See below)
    validate({ id: 'string' }),
    (req, res, next) => {
        res.end('ok');
    }
);

Advanced usage

Besides superstruct's built-in types, you can build custom ones!


const { validate, superstruct, struct } = require('express-superstruct');
/* ... */

const types = {
    email: value => isEmail(value),
    passwod: value => validatePassword(value),
    numeric: value => isNumeric(value)
};

const customStruct = superstruct({ types });

const schema = {
    email: 'email', 
    password: 'password',
    captcha: 'boolean?' // Optional field
};

app.post(
    '/login', 
    validate(schema, customStruct),
    (req, res, next) => {
        res.end('ok');
    }
);

app.post(
    '/emails', 
    validate({ emails: ['email'] }, struct),
    (req, res, next) => {
        console.log(req.body.emails); // I'm an array of emails
        res.end('ok');
    }
);

You can pass a more complex Struct too!

const schema = {
    name: 'string & !empty', // !empty may be another custom type!
    emails: struct.optional(['email'])
};

app.post(
    '/user/update', 
    validate(schema, struct),
    (req, res, next) => {
        res.end('ok');
    }
);

/* ... */

Default values are supported:

const schema = [{
    name: 'string & !empty', // !empty may be another custom type!
    emails: struct.optional(['email']),
    foo: struct.optional(['string'])
}, { foo: 'bar' } ];

app.post(
    '/user/update',
    validate(schema, struct),
    (req, res, next) => {
        // req.body.foo === 'bar' if foo is not send in the request
        res.end('ok');
    }
);

/* ... */

Handling validation error

const { validate, ValidationError } = require('express-superstruct');
const express = require('express');
const app = express();

app.post(...);

app.use((err, req, res, next) => {

    // If you want to set a custom error
    if(err instanceof ValidationError) {
        return res
            .status(400)
            .json({ message: err.message }); // Superstruct's verbose message
    }

});