@dry-express-responses/zod
TypeScript icon, indicating that this package has built-in type declarations

0.0.43 • Public • Published

Credit to packages used in this project

Description

A small ExpressJS middleware written in TypeScript that wraps around http-status-codes to send consistent responses, reducing the instances of res.status, res.send and having to pass a status code and its associated message.

How to use

Step 1.1

Install dry-express-responses

npm install @dry-express-responses/core @dry-express-responses/types
yarn add @dry-express-responses/core @dry-express-responses/types
pnpm add @dry-express-responses/core @dry-express-responses/types

Step 1.2

In addition to responses, an optional global error handler middleware with errors, and validation errors using zod or yup is also available. The zod/yup packages are only required for validation errors, @dry-express-responses/errors can work on its own, for validation errors both @dry-express-responses/errors and @dry-express-responses/zod (or yup) are required.

npm install @dry-express-responses/errors @dry-express-responses/zod @dry-express-responses/types
yarn add @dry-express-responses/errors @dry-express-responses/zod @dry-express-responses/types
pnpm add @dry-express-responses/errors @dry-express-responses/zod @dry-express-responses/types

Step 2

Create a file in src called dry-express-responses.d.ts and copy the following content, this is required for the types to work.

import {
	BadRequest,
	Created,
	Forbidden,
	InternalServerError,
	NotFound,
	Ok,
	Unauthorized,
} from '@dry-express-responses/types';

declare global {
	declare namespace Express {
		export interface Response {
			ok: Ok;

			created: Created;

			badRequest: BadRequest;

			unauthorized: Unauthorized;

			forbidden: Forbidden;

			notFound: NotFound;

			internalServerError: InternalServerError;
		}
	}
}

Example usage

import {dryExpressResponses} from '@dry-express-responses/core';
import {
	dryExpressErrors,
	BadRequestError
} from '@dry-express-responses/errors';
import {ZodValidationError} from '@dry-express-responses/zod';
import {
	zParse,
	zSafeParse
} from '@dry-express-responses/zod-request-validation';
import express from 'express';
// Can be used with yup instead
import z from 'zod';

const app = express();

// Can use either or both of the middleware
app.use(dryExpressResponses);

app.get('/', (req, res) => {
	res.badRequest({
		data: {
			email: 'foo@bar.com',
		},
		message: 'This is a bad request',
		errors: [
			{
				field: 'email',
				message: 'invalid email',
			},
		],
	});
});

app.post('/oops', (req, res) => {
	throw new BadRequestError();
});

app.put('/validate', (req, res) => {
	// Validate body/query/params directly and return a typesafe version
	const result = zSafeParse({
		body: z.object({
			email: z.string(),
		}),
		query: z.object({
			id: z.string(),
		}),
		params: z.object({
			color: z.string(),
		}),
	}, req);
	// Or just throw ZodValidationError directly on validation error using zParse
	const {body} = zParse({
		body: z.object({
			email: z.string(),
		}),
		query: z.object({
			id: z.string(),
		}),
		params: z.object({
			color: z.string(),
		}),
	}, req);

	// Lets zod infer that data exists if success = true
	if (!result.success) {
		// Uses express-async-errors under the hood
		throw new ZodValidationError(result.error);
	}

	return res.ok({
		// Both are typesafe!
		data: body.email ?? result.body.email,
	});
});

// Has to be placed after all the routes and middleware
app.use(dryExpressErrors({
	// Optional, defaults to console.error
	logger: console.log,
	// Optional data to pass to the response (can be any key/value)
	version: 5
}));

app.listen(3000, () => console.log('listening on port 3000'));

Don't want to use a middleware or overload response?

import {dried} from '@dry-express-responses/core';
import express from 'express';

const app = express();

app.get('/', (req, res) => {
	dried(res).ok();
});

// Pass response once!
app.get('/reuse', (req, res) => {
	const dry = dried(res);

	if (req.query.foo === 'bar') {
		return dry.badRequest({
			message: 'Wrong foo',
			errors: [
				{
					field: 'foo',
					message: 'Received bar instead of foo!',
				},
			],
		});
	}

	if (!req.query.foo) {
		return dry.notFound({
			message: 'Foo was not found :(',
		});
	}

	dry.ok();
});

app.listen(3000, () => console.log('listening on port 3000'));

Package Sidebar

Install

npm i @dry-express-responses/zod

Weekly Downloads

0

Version

0.0.43

License

ISC

Unpacked Size

13.4 kB

Total Files

19

Last publish

Collaborators

  • omrilevy0197