ejvm v1.0.5
EJVM
Express middleware written in Typescript for validating request-payloads against JSON schemas.
The motivation for building this library were these constraints: 1. It should be written in Typescript 2. It should use the current JSON schema standard 3. It should be as simple as possible 4. It should have reasonable defaults
Installation
yarn add ejvmNote: EJVM supports draft-07 only!
Note: The middleware expects the
req.bodyproperty to contain proper JSON. Use the body-parser middleware to handle this for you. Keep in mind that you must include the content-type headerContent-Type: application/jsonin your requests.
Usage
Example application
This library includes a documented example application at src/example. To run it, clone the repository,
install the dependencies and start the application:
$ git clone https://github.com/MrSchneepflug/ejvm
$ cd ejvm
$ yarn install
$ yarn exampleExample request with curl:
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"name": "some name"}' \
http://localhost:3000/persons{"success":true}Simple Example
Lets say you want to build a CRUD interface for persons. To add a new person you would POST a JSON payload describing a person to a /persons endpoint.
First thing is to describe the desired schema for the person-payload. See http://json-schema.org/ for an in-depth explanation.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/schemas/person.json",
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
}
}Put this schema definition either in a separate .json file or directly in your code.
// load schema from separate file ...
const schema = JSON.parse(fs.readFileSync("/path/to/schema.json", "utf8"));
// ... or define schema directly in your code.
const schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/schemas/person.json",
"type": "object",
[...]
};You need to import the validate and isJsonSchemaValidationError functions. Also add the body-parser middleware.
import {validate, isJsonSchemaValidationError} from "ejvm";
import bodyParser from "body-parser";Use the body-parser middleware before any route definition:
app.use(bodyParser.json());Use the schema to create a new validation-middleware by calling the validate function.
app.post("/persons", validate(schema), (req: Request, res: Response): void => {
// logic to store the person
});Lastly, in order to catch the validation-errors you need to have an error-handler in place:
app.use((err: Error | JsonSchemaValidationError, req: Request, res: Response, next: NextFunction): void => {
if (isJsonSchemaValidationError(err)) {
// handle the error here, e.g.:
res.status(400);
res.json({
statusText: "Bad Request",
jsonSchemaValidation: true,
validation: err.validationErrors,
});
} else {
// this is not a JsonSchemaValidationError, so do not handle it here
// and let the next middleware/finalhandler handle it
next(err);
}
});To actually add a new person you need to include valid JSON with a name and optionally an age property. Example request with curl:
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"name": "some name", "age": 65}' \
http://localhost:3000/personsUsing multiple schemas
Sometimes it makes sense to use multiple schemas. For example if you want to reuse a specific schema several times.
Example
employee.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/schemas/employee.json",
"type": "object",
"required": ["department", "person"],
"properties": {
"department": {
"type": "string"
},
"person": {
"$ref": "http://example.com/schemas/person.json"
}
}
}person.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/schemas/person.json",
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
}
}In this case you would pass an array with any additional schema as the second parameter to validate().
const employeeSchema = require("/path/to/employee.json");
const personSchema = require("/path/to/person.json");
app.post("/employees", validate(employeeSchema, [personSchema]), (req: Request, res: Response): void => {
// ...
});Note: Pass the configuration object for EJVM as third parameter to
validate()if you want to use additional schemas.
Tests
$ yarn install
$ yarn test