0.1.3 • Published 3 years ago

express-router-helpers v0.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

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
0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago

0.0.1

3 years ago