ejvm
v1.0.5
Published
Validates JSON payloads
Downloads
4
Maintainers
Readme
EJVM
Express middleware written in Typescript for validating request-payloads against JSON schemas.
The motivation for building this library were these constraints:
- It should be written in Typescript
- It should use the current JSON schema standard
- It should be as simple as possible
- It should have reasonable defaults
Installation
yarn add ejvm
Note: EJVM supports draft-07 only!
Note: The middleware expects the
req.body
property 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/json
in 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 example
Example 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/persons
Using 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