@phoenix35/express-async-methods

0.1.0 • Public • Published

@phoenix35/express-async-methods

My own take at making express compatible with async functions.
Heavily inspired by @awaitjs/express and @root/async-router.

Most credits go to them.

How to use

addAsync

addAsync(
  app[, methods ]
);

The default methods that this adds support to

methods = [ "use", "delete", "get", "head", "param", "patch", "post", "put" ]

If you don't use a router, wrap your express app with this.

const express = require("express");
const { addAsync } = require("@phoenix35/express-async-methods");

const app = addAsync(express());

// Supports error-handling middleware
app.useAsync(async (err, req, res, next) => {
  await asyncLog(err.stack);

  res.status(500).send("Something broke!");
});

// Supports any routing
app.getAsync("/users/:userId", async (req, res) => {
  const userInfo = await dbFetch({ user: req.params.userId });

  res.json(userInfo);
});

Router

Router(
  [[ options, ] methods ]
)

options is the options object you would pass to the creation of the router instance
See addAsync for the default methods.

If you want to use a router, import the async-ready version.

const express = require("express");
const { Router } = require("@phoenix35/express-async-methods");

const app = express(); // This app isn't async friendly.
const router = Router(); // But this router is.

router.getAsync("/i-am-error", async (req, res) => {
  await new Promise(resolve => {
    setTimeout(resolve, 100);
  });

  throw new Error("You summoned an error, you devil!");
});

app.use(router);

wrap

If you want granular control, you can wrap individual callback functions.
(NOT for app.param, see below).

const express = require("express");
const { wrap } = require("@phoenix35/express-async-methods");

const app = express();

app.put("/users/:userId", wrap(async (req, res) => {
  await dbUpdate({ user: req.params.userId, newInfo: req.body });

  res.sendStatus(204);
}));

// Regular methods can still be used without wrapping
app.get("/users/:userId", (req, res, next) => {
  dbFetch({ user: req.params.userId }, (err, userInfo) => {
    if (err)
      return next(err);

    res.json(userInfo);
  })
});

wrapParam

Because of the specific signature of app.param, use wrapParam instead.

const express = require("express");
const { wrap, wrapParam } = require("@phoenix35/express-async-methods");

const app = express();

app.param("userId", wrapParam(async (req, res, next, id) => {
  const userInfo = await dbFetch({ user: id });

  if (userInfo == null) {
    throw new TypeError("Failed to load user");
    // next will be called automatically
  }

  req.user = userInfo;
  // next will be called automatically
}));

app.put("/users/:userId", wrap(async (req, res) => {
  await dbUpdate({ user: req.user.id, newInfo: req.body });

  res.sendStatus(204);
}));

Note that app.paramAsync and Router.paramAsync are properly created and handled by default.

Readme

Keywords

Package Sidebar

Install

npm i @phoenix35/express-async-methods

Weekly Downloads

0

Version

0.1.0

License

MPL-2.0

Unpacked Size

38.9 kB

Total Files

16

Last publish

Collaborators

  • phoenix35