When writing express apps, input validation is a total chore. You can't trust anything about the request body because it's parsed into dynamically typed data structures.
JSON Schema is a standard for validating JSON data structure. You can validate schemas using epoberezkin/ajv in JavaScript.
$ npm install --save ajv
For an example, let's validate the signup route.
{
"title": "POST /signup",
"description": "Create a new account.",
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string",
"format": "password"
},
"tos": {
"description": "Terms of service agreement.",
"type": "boolean"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
}
},
"required": [
"email",
"password",
"tos"
]
}
Compile the schema.
var AJV = require("ajv")
var ajv = new AJV()
var schema = require("signup.json")
var validate = ajv.compile(schema)
To validate data, call the compiled function.
validate({
email: "invalid"
})
// false
validate({
email: "[email protected]",
password: "whatever",
tos: true
})
// true
When the validation returns false, errors are attached to the function (kind of weird tbh, but JavaScript is single-threaded so there's no risk of overwriting errors.)
validate("invalid")
console.error(validate.errors)
Instead of manually checking the request body in each test, use middleware.
// validate.js
var AJV = require("ajv")
var ajv = new AJV()
module.exports = function (schema) {
// compile schema once
var validate = ajv.compile(schema)
return function (req, res, next) {
if (validate(req.body)) {
return next()
}
// not valid
res.status(400).json({
error: validate.errors[0].message
})
}
}
To validate params for a route, include the middleware.
var express = require("express")
var validate = require("./validate")
var app = express()
app.use(require("body-parser").json())
var schema = require("./signup.json")
app.post("/signup", validate(schema), function (req, res, next) {
// req.body is valid
})
Invalid requests are rejected. The benefit of this approach is that JSON Schema is easier to write than custom validation code, and also serves as documentation.
Thanks for reading,