Writing Async/Await Middleware in Express
Tags: node, javascript, express
Published: 2017-11-12 03:01:58

---
title: Writing Async/Await Middleware in Express
published: true
description: Move your Promise-based requests into asynchronous middleware functions and clean up those router blocks!
canonical_url: https://dev.to/geoffdavis/writing-asyncawait-middleware-in-express
cover_image: https://source.unsplash.com/VP25o26erko/1100x420
tags: node,javascript,express
---

Do you use Promise-based data fetching in your [Express](https://expressjs.com) apps? Are you sick of nesting route-handling code statements inside `.then()` method calls? Want to learn `async/await` in a practical, applicable way? If your answer was "yes!" to any of those questions, read on, and I will help you move those Promises into asynchronous [middleware](https://expressjs.com/en/guide/writing-middleware.html) functions.

(If you just want to see my example repository with finished code, [check it out here](https://github.com/geoffdavis92/express-async-await-middleware))

## The Problem

If you are anything like me, your Express router fetches data by requesting data from the respective API endpoint or database using a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)-based approach. This is a modern approach to alleviate a problem that many developers call "[callback hell](http://callbackhell.com/)". 

The following snippet is what modeled after one of my current Express side projects; note the asynchronous, Promise-based structure of passing data in lieu of synchronous, function-based callbacks.

```javascript
/* Example of a Promise-based data request approach */
const endpoint = 'https://jsonplaceholder.typicode.com/posts/1';
app.get('/',(req,res) => {
  PromiseBasedDataRequest(endpoint).then(data => {
    const { title, body } = data;
    req.render('post', { title, body });
  })
})
```

So we're using relatively flat Promises versus a pyramid of callback functions on top of callback functions, great! 

But once we have our data passed through the chain of `.then()` calls, we now have to write a bunch of code to process the data and/or send the actual response for the router request. Some developers will handle their code this way, and if that works for you, fantastic; however, now that async/await is supported in Node, it doesn't *have* to be this way.

## My Solution

With support for [asynchronous functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) (often referred to as `async/await`) in Node.js as of v7.6, we can now extract data directly from a resolved `Promise` in an `async` middleware function and pass that data to the final router callback in a clean and easily-readable manner.

Consider the following middleware function as an update to the previous snippet:

```javascript
const endpoint = 'https://jsonplaceholder.typicode.com/posts/1';
const asyncMiddleware = async (req,res,next) => {
  const data = await PromiseBasedDataRequest(endpoint);
  req.data = data.json()
  next()
}
```

You may noticed we added a few things:

1. The [`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) keyword in front of the function declaration; this indicates to the engine that somewhere in the function body, there is a call to a Promise, and often that a Promise uses the `await` keyword (see #2).
2. The [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) keyword in front of the `PromiseBasedDataRequest` call assigned to the `data` variable; this indicates to the engine that all other code execution should be halted until the Promise resolves. (i.e. the application "awaits" the result of the request) This also allows the `PromiseValue` to be assigned to a variable and used later.

After that, the `data` fetched from `endpoint` is assigned to a property on the `req`/request object; this allows the value to be accessed later on in the application via `req.data`. Finally, a call to `next()` sends the `req` and `res` objects to the next piece of middleware, or, when no other middleware is in place, to the final route callback.

Let's put our `asyncMiddleware` function in the router's chain; in Express, this happens between the route and the final callback. (you can place as many middleware functions here as you'd like, just do not forget to call `next()` at the end of each!)

```javascript
app.get('/', asyncMiddleware, (req,res) => {
  const { title, body } = req.data;
  req.render('post', { title, body });
})
```

Wow! So fresh, so clean. 

Now we have a very flat and readable router declaration, with the bulk of our code that would normally sit in the router callback^[[1]](#note1) instead situated in a middleware function, and the data being synchronously passed into the final router callback function.

If you would like to see this implementation/pattern in a "completed" project, check out [the example repo](https://github.com/geoffdavis92/express-async-await-middleware) I set up for this article. Follow the instructions in the README file to get started; if you find something wrong or need help, feel free to [file an issue](https://github.com/geoffdavis92/express-async-await-middleware/issues/new) and I will be happy to review with you.

## The Motivation

I was motivated to research this solution because I wanted to learn and experiment more with `async`/`await` functions and Express middleware; the best way I learn is by making test projects and having hands-on experience implementing features.

I plan to use this exact pattern of writing async middleware in a side project that utilizes the Javascript [Contentful SDK](https://github.com/contentful/contentful.js) and [MySQL driver](https://github.com/mysqljs/mysql). The current implementation I have in this project is exactly like the first code snippet example: the respective API is called and wraps the actual `res`/response call in either a callback or a `.then()` method call. By rewriting these features into middleware functions, I aim to simplify the writing of new router paths/API endpoints and hopefully increase code reusability.

## Conclusion

In closing, utilizing `async`/`await` as your Express middleware implementation helps keep your code reusable, readable, and up-to-date with current coding conventions.

I hope my little Saturday experiment helped you better understand asynchronous functions and Express middleware. Thanks for reading!

<div id="furtherreading"></div>

### Further Reading

* [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
* [await keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)
* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
* [ExpressJS](https://expressjs.com)
* [Guide to Asynchronous Javascript](https://medium.com/dev-bits/writing-neat-asynchronous-node-js-code-with-promises-32ed3a4fd098)

<div id="note1"></div>

### Notes

\[1]: According to [this Stack Overflow post](https://stackoverflow.com/questions/20068467/do-never-resolved-promises-cause-memory-leak), unresolved Promises do not pose any serious threat of a memory leak.