26
loading...
This website collects cookies to deliver better user experience
type RequestBody<T> = Request<{}, {}, T>;
interface UserBody {name: string};
app.post("/user", (req: RequestBody<UserBody>, res) => {
return addUser(req.body.name);
})
addUser
function, which will crash the whole server as the error is not caught.type RequestBody<T> = Request<{}, {}, T>;
interface UserBody {name: string};
app.post("/user", (req: RequestBody<UserBody>, res) => {
if (!req.body.name) return res.sendStatus(400); // we added this
return addUser(req.body.name);
})
const schema = {
type: "object",
properties: {
foo: {type: "integer"},
bar: {type: "string", nullable: true}
},
required: ["foo"],
additionalProperties: false
}
interface UserPostRequest {
foo: integer,
foo: string
}
req.body
matched the schema:// function that creates middleware by compiling the supplied schema
function validateBody(schema) {
// compile schema
const validate = ajv.compile(schema);
// middleware that returns error if schema is not ok
return (req, res, next) => {
if (!validate(req.body)) return res.status(400).json(validate.errors);
return next();
};
}
const schema = {
type: "object",
properties: {
name: {type: "string"},
},
required: ["name"],
}
app.post("/user", validateBody(userSchema), (req, res) => {
return addUser(req.body.name); // name will never be undefined
})
schema_definition.ts
file contains the interfaces we would like to convert into json schemas.schemaGenerator.js
script that will use this library to convert said file into schema._schema.ts
file that will be generated, all it will do is export the json schema so we can import it elsewhere. Essentialy a .json
file wrapped in a .ts
file.// schema_definition.ts
export interface UserPostRequest {
name: string;
}
// schemaGenerator.js
const path = require("path");
const tjs = require("typescript-json-schema");
const fs = require("fs");
const settings = {
required: true,
ref: false,
};
const compilerOptions = {
strictNullChecks: true,
};
const program = tjs.getProgramFromFiles([path.resolve("schema_definition.ts")], compilerOptions, "./");
const schema = tjs.generateSchema(program, "*", settings);
fs.writeFileSync(
"_schema.ts",
"const schema = " + JSON.stringify(schema) + " as const;\nexport default schema.definitions;"
);
package.json
:scripts: {
"schema": "node schemaGenerator.js"
...
}
npm run schema
will create a _schema.ts
file in the root directory.// index.ts
import express, { Request, Response, NextFunction } from "express";
import _schema from "./_schema";
import { UserPostRequest } from "./schema_definition";
import Ajv from "ajv";
const app = express();
app.use(express.json());
const ajv = new Ajv();
// validation middleware
function validateBody(schema: object) {
const validate = ajv.compile(schema);
return (req: any, res: any, next: NextFunction) => {
if (!validate(req.body)) return res.status(400).json(validate.errors);
return next();
};
}
// helper type
type RequestBody<T> = Request<{}, {}, T>;
function addUser(name: string) {}
app.post("/user", validateBody(_schema.UserPostRequest), (req: RequestBody<UserPostRequest>, res: Response) => {
return addUser(req.body.name); // name will never be undefined
});
app.listen(3000);