DEV Community

Cover image for Writing Async/Await Middleware in Express

Writing Async/Await Middleware in Express

Geoff Davis on November 12, 2017

Do you use Promise-based data fetching in your Express apps? Are you sick of nesting route-handling code statements inside .then() method calls? Wa...
Collapse
 
andywer profile image
Andy Wermke

If switching frameworks in an option you might wanna check out koa v2 (koajs.com). koa v1 used generator functions, but koa v2 comes with a 100% promise-based API, so you have support for async/await route handlers and middlewares out of the box!

Express probably has the most evolved middleware ecosystem of all node server frameworks, but koa's is quite comprehensive as well :)

Collapse
 
josser profile image
Dmitry Chirkin

There is one thing in your code which may break: (sorry if my english is not good)

Take a look at this code:

function someethingAsync() {
  return new Promise((resolve, reject) => {
    setTimeout(() => { reject() }, 1000);
  })
}

async function test() {
  const data = await someethingAsync();
  console.log('Will you see me?')
  console.log(data);
  console.log('No')
}

test();

If you run it, you will never see console.log's
And the same is true for you middleware code
If PromiseBasedDataRequest will be rejected then you never reach next() and execution will hang.

Rule of thumb here is simple: when we trying to connect Promise-style and callback-style code and you are somewhere in callback, you should always write .catch() block.

Collapse
 
josheriff profile image
Jose • Edited

You don't need the "then" since the await do the job.

Also you don't need the next() at the end, if I'm not in a mistake, async express just go next when finish solving all the promises inside the function.

I'm in the mobile now but try to put an example later if you want

Collapse
 
geoff profile image
Geoff Davis

Thanks! I updated my snippets.

Regarding the next() call, I'll have to check that out.

Collapse
 
josheriff profile image
Jose

I mean this:

const endpoint = 'jsonplaceholder.typicode.com/posts/1';
const asyncMiddleware = async (req,res) => {
const data = await PromiseBasedDataRequest(endpoint);
req.data = await data.json() // if I remember well data.json() its a
//promise too thats why about another
//await
return req.data
}

// the workflow continues

Async await it's almost have a "syncronous" code.

Collapse
 
costica profile image
costica

Thanks for the snippet, exactly what i was looking for

Collapse
 
chrismarx profile image
chrismarx

I've adopted this library for automatically adding async/promise support in express routes, curious if you've looked at it and what your thoughts are -

npmjs.com/package/express-promise-...

Collapse
 
nax3t profile image
Ian Schoonover

Great article! Thanks :)

I noticed you have: req.render('post', { title, body });
shouldn't it be: res.render('post', { title, body }); ?

Collapse
 
geoff profile image
Geoff Davis

Good catch! I'll update my snippets

Collapse
 
itzhakfranco profile image
itzhakfranco

found it super helpful. Thanks

Collapse
 
saifalfalah profile image
Saif Al Falah

This was extremely helpful. Thanks

Collapse
 
nvcken profile image
Ken

Thanks your post.
As I know we need try/catch to ensure safety in async/await function so that have you know anyway to better manually put try/catch in each middeware function ?