SDK

General Reference

https://docs.aws.amazon.com/general/latest/gr/Welcome.html

Contents:

  • Region & Endpoints
  • Security credentials
  • ARN format & name spaces
  • Signing request
  • Service Limits
  • IP Address ranges
  • Retries
    • Each AWS SDK implements automatic retry logic (see SDK configuration)
    • What to retry (general)
      • 5xx or throttle errors from server
      • NOT 4xx errors (client error, revise request)
    • Each AWS SDK implements exponential backoff algorithm, with jitter (random) to avoid conflict. https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
    • To debug and inspect retries, AWS.events.on('retry', function(resp){...
  • S3 Clientside Encryption

SDK for Javascript

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/welcome.html

Basics

For Node.js (EC2, Lambda), for browser. Amplify extends SDK for browser and provides declarative interface.

Setup

Node.js:

  • EC2 container - choose an image with the environment
  • EC2 - install
  • Lambda - already provided

Browser:

  • Can build a smaller one for selected services only
  • CORS:
    • Many services (S3) requires CORS configuration on resources

Configuration

Minimum - region & credentials (note: if load from user shared config, credentials could be null if resume role, it only become available after actually used)

How to configure:

  • using the global configuration object (for every service)
    • AWS.config.update({region:'...
    • Environment variable like AWS_REGION
    • loading shared config & credential from ~/.aws (see below)
  • configure per service class (for all instances hereafter)
    • AWS.config.ec2 = {region: 'us-west-2', apiVersion: '2016-04-01'};
  • or pass extra configuration to service object when creating them (take all the configuration parameters as the global configuration including region & credentials).
    • new AWS.SomeService({...
  • load from user shared config & credentials (default in ~/.aws dir) (see here)

or

process.env.AWS_SDK_LOAD_CONFIG = true; 
const AWS = require('aws-sdk');

Examples: using cognito ID pool

AWS.config.region = ...
// from cognito ID pool
AWS.config.credentials = new AWS.CognitoIdentityCredentials({...


// another style
var myCredentials = new AWS.CognitoIdentityCredentials({IdentityPoolId:'IDENTITY_POOL_ID'});
var myConfig = new AWS.Config({
  credentials: myCredentials, region: 'us-west-2'
});

// using 'update' 
myConfig = new AWS.Config();
myConfig.update({region: 'us-east-1'});

Example: per-service instance

var ec2_regionA = new AWS.EC2({region: 'ap-southeast-2', maxRetries: 15, apiVersion: '2014-10-01'});
var ec2_regionB = new AWS.EC2({region: 'us-east-1', maxRetries: 15, apiVersion: '2014-10-01'});

API Version Lockup

API version identified by 'YYYY-MM-DD'

Locking up recommended in production environment.

To lockup, do it individually when instantiating service object, or globally:

AWS.config.apiVersions = {
   dynamodb: '2011-12-05',
   ec2: '2013-02-01',
   redshift: 'latest'
};

Work with Services

Importing the service class:

  • require('aws-sdk') get everything
  • require('aws-sdk/clients/SERVICE') get individual service + require('aws-sdk/global') get the global namespace, smaller footage doing things this way

Creating service object:

  • Pass configurations for the object (override global configurations)
  • Pass {params:{ someParameter: 'someDefaultValue'}} then the parameter would not be needed to be provided with every invocation (unless for overriding)

Invoking a service include full request / response & retry

AWS.Request / AWS.Response object encapsulates the request & responses.

Logging - see document

Asynchronous calling

  • All calls asynchronous
  • Manners:
    • Pass callback as last parameter in service method calls
      • function(error, data) {...} (not arrow style)
      • "this" in callback for most services refer to the Response object, and through it can then refer to the Request object
      • In this manner the call is sent out
    • No callback parameter, register callback
      • Without callback passed in, method calls return the Request object
      • Must manually call .send() method
      • Register callbacks (multiple) before send
        • ... request.on('success', function(response) {...})
        • can chain up ".on(...).on(...).send()"
        • common callbacks:
          • 'success', function(response)
          • 'error', function(error,response)
          • 'complete', function(response){ if (response.error)...
    • Use promises (after calling a service method without callback to obtain a Request not sent yet)
      • var promise = request.promise(); - immediately send and obtain the promise
    • Request with Stream (file downloading with S3, etc.) see document

Response Object

  • properties "error" & "data"

Retry

See https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#retryDelayOptions-property

Someone said most services by default retry 3 times, while DynamoDB retry 10 times (can be set).

Set maximum retries globally: AWS.config.maxRetries = 5

Set for individual service (DynamoDB): new AWS.DynamoDB({maxRetries: 5})

Inspect & diagnose:

On global level

AWS.events.on('retry', function(resp) {
  if (resp.error && resp.error.retryable) {
    var date = new Date();
    console.log(date, '| Retrying request for the ' + resp.retryCount + 'th time.');
    console.log(date, '| Retry triggered by', err.code, err.message);
  }
}); 

On individual request level

req.on('retry', function() { ... });