express-router-helpers v0.1.3
Express Router Helpers
create your route handlers easier and autoload routes
Install
# npm
npm i express-router-helpers
# yarn
yarn add express-router-helpers
Usage
Create Handler
import express from "express";
import { createHandler } from "express-router-helpers";
const app = express();
const creator = createHandler({
requiredData: ["username"], // req.body
requiredQuerys: ["rol"], // req.query
requiredParams: ["id"], // req.params
});
const getUser = creator(async (req, res) => {
const { username } = req.body;
const { rol } = req.query;
const { id } = req.params;
const user = await getUserData({ username, rol, id });
res.json(user);
});
app.post("/user/:id", getUser);
when someone fetch
the endpoint /user/:id
, the function getUser
won't be executed if the required info is not passed.
const res = await fetch("/user/123", { method: "POST" });
const data = await res.json();
console.log(data);
// {
// message: "Validation Failed",
// errors: [
// {
// resource: "Handler",
// field: "username",
// code: "missing",
// message: 'Missing required field "username" from body',
// },
// { field: "rol", ... },
// ],
// }
Change status code when fields are missing
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
statusCodeOnMissingFields: 200, // default: 422
// ...
})((req, res) => {
// ...
});
Change resource property in error objects
// app
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
resource: "GetUserInfo", // default: "Handler"
// ...
})((req, res) => {
// ...
});
// on fetch
const data = await fetch("...").then((res) => res.json());
console.log(data.errors.at(0).resource);
// => "GetUserInfo"
Set a maximum number of missing fields errors to send
// app
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
maxMissingFields: 1,
// ...
})((req, res) => {
// ...
});
// on fetch - no matter how many fields are missing,
// there is only one on errors property
const data = await fetch("...").then((res) => res.json());
console.log(data.errors.length);
// 1
Create your own errors
// app
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
onMissingRequiredFields: (missingField) => {
return {
message: "You missed one field",
missingField,
info: "this is required",
};
},
// ...
})((req, res) => {
// ...
});
// on fetch
const data = await fetch("...").then((res) => res.json());
console.log(data.errors.at(0));
// {
// message: "You missed one field",
// missingField: "username",
// info: "this is required",
// }
Optional fields
With optional fields you only will have auto-completion on your text editor
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
optionalData: ["maxUserPhotos"],
optionalQuerys: ["getExtraInfo"],
})((res, res) => {
// ...
});
Set default values for optional fields
import { createHandler } from "express-router-helpers";
const getUser = createHandler({
optionalData: ["maxUserPhotos"],
optionalQuerys: ["getExtraInfo"],
defaults: {
data: { maxUserPhotos: 20 },
querys: { getExtraInfo: true },
},
})((res, res) => {
res.json({ data: req.body, querys: req.querys });
});
// on fetch
const data = await fetch("/user/123").then((res) => res.json());
console.log(data);
// => { data: { maxUserPhotos: 20 }, querys: { getExtraInfo: true } }
Load directory
import express from "express";
import { loadDirectory } from "express-router-helpers";
const app = express();
const DIR = "./routes";
// directory structure
// routes
// └─ index.js
// └─ user
// └─ index.js
// └─ :id.js
//
await loadDirectory(DIR, app);
// this load 3 routes: /, /user, /user/:id
app.listen(3000);
How to use it
To use loadDirectory
create directory, in this example we are gonna name it routes
. to create your routes just name your files inside the directory the same as you'd do in a normal way. Example: convert this path app.get("/user/gallery/photo/:photoId", handler)
into this file ./routes/user/gallery/photo/:photoId.js
, like this:
// routes
// └─ user
// └─ gallery
// └─ photo
// └─ :photoId.js
Methods
Ok, but now how do I define the methods that will accept the routes. You have to export a function named as the method you want to use (in lower case).
// /routes/user/:id.js
export function get(req, res) {
res.json({ id: req.params.id });
}
export function post(req, res) {
res.json({ id: req.params.id });
}
export function put(req, res) {
res.json({ id: req.params.id });
}
How to export a "delete" method
delete is a reserved word, so how can I export a function named delete, like this:
function deleteUser(req, res) {
res.json({ message: "User deleted" });
}
export { deleteUser as delete };
Using middlewares
to use middlewares simply export an array with all the middlewares you're gonna use and as the last one your handler
function processUserMiddleware(req, res, next) {
// ...
next();
}
function privateUserMiddleware(req, res, next) {
// ...
next();
}
function getUser(req, res) {
// ...
}
export const get = [processUserMiddleware, privateUserMiddleware, getUser];
Options
import { loadDirectory } from "express-router-helpers";
await loadDirectory("./routes", app, { basePath: "/api", verbose: true });
// basePath will load all routes with the base path you pass, in this case /api
// example /api/ /api/user /api/user/:id /api/auth/ /api/auth/login
// verbose will let you know how many and which paths have been loaded