How to use promise design patterns on AWS API's
We all talk about callback hell in JavaScript world. There are a few ways we can follow to mitigate callback hell, its a matter of time, before it catches up with us. One of the ways we can get better of it is use "Promise".
A simple Callback sample
Here's a classic example of how I read contents from an S3 bucket first with callback pattern, then later with promise. This change is not drastic, but benefits are. It's not just code maintenance, readability also improves by miles. The more you follow promise patterns more are the chances you stay clear with context and re-usability. Finally, something that brings smile to perfectionists - Unit tests. Promise makes it lot more easier for unit tests.'use strict'; var config = { accessKeyId: 'SDFLGSDFGLJSDFGL', secretAccessKey: 'sdasdfasdflfmasdlasdffm/asdf', region: 'us-east-1' }; var tipsBucketConfig = { 'Bucket': 'somebucket', 'Key':'tips_xyz.json' }; var AWS = require('aws-sdk'); var awsConfig = require('aws-config'); var s3 = new AWS.S3(awsConfig(config)); var listAllBuckets = function() { s3.listBuckets({}, function(err, data) { if(err) { console.log('ERROR: Failed to collect any information about buckets'); } else { var buckets = data.Buckets; var owners = data.Owner; for (var i=0; i<buckets.length; i+=1) { var bucket = buckets[i]; console.log(bucket.Name + ' created on ' + bucket.CreationDate); } for (var i=0; i<owners.length; i+=1) { console.log(owners[i].ID + ' created on ' + owners[i].DisplayName); } } }); }; listAllBuckets();
Of course, we can make this code better, by creating a callback function that can be passed to "listBuckets" method. I bet you can, imagine for a minute, our requirement gets a little more complicated. If we have multiple buckets and we need to dig into one of the bucket for information, you can easily see the constrictor tightening its grip.
Promise Approach
This is where promise helps. And here's how we can convert the code above to a promise pattern'use strict'; var config = {accessKeyId: 'SDFLGSDFGLJSDFGL', secretAccessKey: 'sdasdfasdflfmasdlasdffm/asdf',region: 'us-east-1' }; var tipsBucketConfig = { 'Bucket': 'somebucket', 'Key':'tips_xyz.json' }; var promise = s3.listBuckets({}).promise(); promise.then(function(data) { var buckets = data.Buckets; var owners = data.Owner; for (var i=0; i<buckets.length; i+=1) { var bucket = buckets[i]; console.log(bucket.Name + ' created on ' + bucket.CreationDate); } for (var i=0; i<owners.length; i+=1) { console.log(owners[i].ID + ' created on ' + owners[i].DisplayName); } }).catch(function(err) { console.log('ERROR: Failed to collect any information about buckets'); });
We have error handler abstracted out. If we need to interrogate a specific bucket, then we will return a promise, that can be re-used a lot more easily than conventional callback pattern.
Let me know your thoughts and as always, thanks for your time.
No comments:
Post a Comment