Skip to content

Instantly share code, notes, and snippets.

@guzmonne
Created December 5, 2016 03:44
Show Gist options
  • Save guzmonne/d9a7fd0d76838b0ea7366788d27e434f to your computer and use it in GitHub Desktop.
Save guzmonne/d9a7fd0d76838b0ea7366788d27e434f to your computer and use it in GitHub Desktop.
AWS.Request - README.md to Medium article

AWS.Request Class on the JavaScript SDK

The AWS JavaScript SDK is a fantastic tool to leverage the power of the AWS services. All the features provided by the cloud giant are accesible through it. And now, after version 2.6.1 it supports webpack, which makes creating bundles of it a breeze. With webpack, we can only include the bits and pieces we need for our application. Want to add a way to upload files to S3? Ineract directly with DynamoDB? Push notification to other clients through SNS? Just add the client you need and start coding. Webpack will trim away all the unnecessary code, leaving our bundle JavaScript as slim as possible.

The best source to undestand the capabilities of the SDK is through it main documentation site. All the information for all AWS serices are listed on it. As the documentation states:

All requests made through the SDK are asynchronous and use a callback interface.

So we need a way to handle this asynchronous behaviour of the SDK. That is why AWS provides us with the AWS.Request class.

Each service method that kicks off a request returns an AWS.Request object that you can use to register callbacks.

This class offers a lot of ways to handle the responses from each AWS services. So we can use the one which makes more sense for us or the project.

In this article, I want to explore through some examples the different ways the AWS.Request class can help us command AWS services. First we'll setup a simple project using hjs-webpack to simplify the creation of webpack's configuration file. We'll then import the AWS SDK and configure it with our credentials. After that is done, we'll create a simple html page from where we'll interact with some AWS services. If you want to follow along you can clone each step from the project repo.

Setup

Let's init a new npm project to keep track of all our dependencies. We'll also use npm scripts to run and build our app.

npm init

As I mentioned on the introduction, we'll be using hjs-webpack to simplify webpack's configuration. This package was created by Henrik Joreteg as an opinionated way to build apps with webpack. I sugges you give it a try if you don't know it. It is not needed to work with the AWS SDK, you can just use webpack as you normally do if you want.

So, let's install through npm the hjs-webpack module and some other necessary dependencies.

npm install --save-dev hjs-webpack css-loader postcss-loader style-loader autoprefixer babel-core babel-loader json-loader webpack-visualizer-plugin babel-preset-es2015 babel-preset-react babel-preset-react-hmre

To handle the visual layer of the project we'll use React. Since this is not meant to be a React article I'll try to add all the code necessary to run the app without issues and try to explain some of the implementation details when needed. If you have any question just ask me directly, or check React's documentation. Add react and react-dom to the project through npm and save the dependencies to our package.json file:

npm install --save react react-dom

Let's configure babel to use es2015 and react presets and to handle Hot Module Replacement. Create a file on your project's root called .babelrc and include the following code:

{
  "presets": ["es2015", "react"],
  "env": {
    "development": {
      "presets": ["react-hmre"]
    }
  }
}

We are ready to build our webpack configuration using hjs-webpack. Let's create a file called webpack.config.js and add the following configuration:

https://gist.github.com/guzmonne/9767a7ee81edff27630adef5e7f88833

Note that we are adding the Visualizer plugin to see how each dependency influence the final size of our bundle. You can see the results by checking the stats.html file on the public folder after every build.

To run our dev server and build our project we'll add a couple of entries to the scripts section of our package.json config.

{
  ...
  "scripts": {
    ...
   "start": "hjs-dev-server",
   "build": "webpack"    
  }
  ...
}

We also have to create the src/index.js and src/app.js files to have something to render on the page. Add these files to the a new src folder:

https://gist.github.com/guzmonne/73fd197ddec3bace834772e173767ded

https://gist.github.com/guzmonne/1bec8905f2ec609c4dd68a5b279021dc

The dev server can be run using our start npm script. Use the command npm start on your console to start the development server. If you now go to http://localhost:3000 you'll be greeted to a typical "Hello, World" page. Try modifing the content of the h1 inside the App component. You should see how webpack takes the changes and updates the page accordingly without doing a full page reload.

We can also build this project using the npm run build command from the console, to see the initial size of our bundle and to check that everything is working fine. After running the command you should see a similar output to the following:

Hash: f5a6e184bfaed9e0ec25
Version: webpack 1.13.3
Time: 4386ms
     Asset       Size  Chunks             Chunk Names
    app.js     189 kB       0  [emitted]  main
index.html  203 bytes          [emitted]
stats.html     547 kB          [emitted]
   [0] multi main 28 bytes {0} [built]
    + 324 hidden modules

The initial size of our file is 189 KB. Which is quite a lot since we have bundled React along our components. It is beyond the scope of this article to explore the different tools provided by webpack to decrease the bundle final size. Nonetheless we'll use this initial filesize to see how the different ways of adding the AWS SDK impact the size of our bundle.

Configuring the AWS JavaScript SDK

AWS JavaScript SDK is available through npm. So we can add it to the project as we did before:

npm install --save aws-sdk

The AWS JavaScript can be added to our project by to means:

  1. import the entire aws-sdk and then instantiate the necessary clients from it.
  2. import the necessary sdk clients for our app.

Let's say that for this particular project we are going to use AWS SNS, S3, and DynamoDB services. So let's check hoy both ways affect our final bundle. We'll create two modules with the needed config. Then we'll add one to our index.js before building our app. After the build process finishes, we'll do the same with the other module and finnaly we'll compare the results.

modules/aws-clients.1.js

https://gist.github.com/guzmonne/ed90b45b190452dc99a44c14c99eb8ed

modules/aws-clients.2.js

https://gist.github.com/guzmonne/d898cc131f0a4870d65cfee032ed0a6b

Comparison

Here is the output for both builds:

# With the first method

Hash: f2080b91e2e72fbca5f4
Version: webpack 1.13.3
Time: 10957ms
     Asset       Size  Chunks             Chunk Names
    app.js    1.39 MB       0  [emitted]  main
index.html  203 bytes          [emitted]
stats.html     805 kB          [emitted]
   [0] multi main 28 bytes {0} [built]
    + 667 hidden modules

---

# With the second method
 
Hash: dd28606fc47261526ac5
Version: webpack 1.13.3
Time: 7715ms
     Asset       Size  Chunks             Chunk Names
    app.js     512 kB       0  [emitted]  main
index.html  203 bytes          [emitted]
stats.html     669 kB          [emitted]
   [0] multi main 28 bytes {0} [built]
    + 489 hidden modules

I think it is pretty clear that the second method is way better to handle our bundle size. It is still quite large compared to our starting bundle but more than half of what you get using with the first method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment