Going Async with Node AWS SDK with Express

When building applications in Node/Express you will quickly come to realize that everything is done asynchronously . But how you accomplish these tasks async can vary.  The ‘old school’ way was to use call backs, which often led to callback hell.  Than came along Promises which we thought was going to solve all the worlds problems, turned out they helped, but did not solve everything.  Finally in Node 8.0 (ok, you could use them in Node 7.6) the support for async/await was introduced and this really has cleaned up and enhanced the readability of your code.

Having the ability to use async/await is great, and is supported out of the box w/ Express.  But what do you do when you using a library which still wants to use promises or callbacks? The case in point for this article is AWS Node SDK.

By default if you read through the AWS SDK documentation the examples lead you to believe that you need to use callbacks when implementing the SDK.  Well this can really lead to some nasty code in the world of Node/Express.  However, as of v2.3.0 of the AWS SDK there is support for Promises.  This is much cleaner than using callbacks, but still poses a bit of an issue if you want to use async/await in your Express routes.

However, with a bit of work you can get your promise based AWS calls to play nicely with your async/await based Express routes.  Lets take a look at how we can accomplish this.

Before you get started I am going to make a few assumptions.

  1. You already have a Node/Express application setup
  2. You already have the AWS SDK for Node installed, if not read here

The first thing we are going to need to do is add reference to our AWS SDK and configure it to use promises.

const AWS = require('aws-sdk');
AWS.config.setPromisesDependency(null);

After we have our SDK configured we can implement our route handler.  In my example here I am placing all the logic inside my handler.  In a real code base I would suggest better deconstruction of this code into smaller parts.

const express = require('express');
const router = express.Router();
const s3 = new AWS.S3();

router.get('/myRoute', async (req, res) => {

    const controller = new sitesController();
    const params = req.params;
    const params = { 
       Bucket: "bucket_name_here"
    };

    let results = {};
    var listPromise = s3.listObjects(params).promise();
    listPromise.then((data) => {
        results = data;
    });

    await Promise.all([listPromise]);

    res.json({data: results })
})

module.exports = router;

Lets review the code above and call out a few important items.

The first thing to notice is the addition of the async keyword in my route handler.  This is what allows us to use async/await in Node/Express.

The next thing to look at is how I am calling the s3.listObjects.  Notice I am NOT providing a callback to the method, but instead I am chaining with .promise().  This is what instructs the SDK to use promises vs callbacks.  Once I have my callback I chain a ‘then’ in order to handle my response.

The last thing to pay attention to is the line with await Promise.All([listPromise]); This is the magic forces our route handler to not return prior to the resolution of all of our Promises.  Without this your call would exit prior to the listObjects call completing.

Finally, we are simply returning our data from the listObjects call via res.json call.

That’s it, pretty straight forward, once you learn that the AWS SDK supports something other than callbacks.

Till next time,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s