http-schemas
Use http-schemas
to describe the 'shape' of a HTTP API in a way that is enforced both at build time and at runtime. In TypeScript source code, HTTP requests in the client code, and route handlers in the server code, will be statically checked against the schema, so usage errors are caught early. At runtime the schema is used to ensure that request and response payloads match the schema. Response payloads are also trimmed of any excess properties to prevent accidental information leaks. A schema may be shared by both client-side and server-side code, giving a single source of truth and ensuring the client and server always agree on their shared API.
http-schemas
uses the rtti
library for specifying and enforcing schemas.
Installation
npm install http-schemas
Example Shared Code (use in both client and server)
NOTE: The v0.10 API is deprecated but still supported.
import {createHttpSchema, t} from 'http-schemas';
export const apiSchema = createHttpSchema({
'POST /sum': {
requestBody: t.array(t.number),
responseBody: t.number,
},
'GET /greet/:name': {
responseBody: t.string,
},
});
Example Client-Side Code
import {createHttpClient} from 'http-schemas/client';
import {apiSchema} from '<path-to-shared-schema>';
const client = createHttpClient(apiSchema, {baseURL: '/api'});
let res1 = client.post('/sum', {body: [1, 2]});
let res2 = client.get('/greet/:name', {params: {name: 'Bob'}});
let res3 = client.get('/sum', {body: [1, 2]});
let res4 = client.post('/sum', {body: 'foo'});
let res5 = client.post('/blah');
Example Server-Side Code
NOTE: The v0.10 API is deprecated but still supported.
import * as express from 'express';
import {createRequestHandler, decorateExpressRouter} from 'http-schemas/server';
import {apiSchema} from '<path-to-shared-schema>';
const apiRouter = decorateExpressRouter({schema: apiSchema});
const app = express();
app.use(express.json());
app.use('/api', apiRouter);
apiRouter.post('/sum', (req, res) => {
let result = req.body.reduce((sum, n) => sum + n, 0);
res.send(result);
});
const greetHandler = createRequestHandler(apiSchema, 'GET', '/greet/:name', (req, res) => {
res.send(`Hello, ${req.params.name}!`);
});
apiRouter.get('/greet/:name', greetHandler);
apiRouter.post('/blah', (req, res) => {});
apiRouter.post('/sum', (req, res) => { req.body.foo[0] });
apiRouter.post('/sum', (req, res) => { res.send('foo') });
app.listen(8000);
Full production-like webserver demo
The best way to see http-schemas
in action is to see it in a real demonstration with documentation. Take a look at http-schemas-webserver-demo, read the docs, run it and play with it yourself.