StackLeader Blog

Post Image
May 27, 2016

Getting Started with AWS Lambda REST Services Part 1 of 3


Overview

This blog post will outline how to configure AWS Lambda functions to synchronously respond to HTTP requests through the API Gateway. Both Lambda and API Gateway are two very hot technologies that allow for serverless infrastructure. Lambda is an Amazon web service that allows you to define a series of functions in languages such as Node.js, Java, and Python. A developer can focus on writing functions for the business logic of the task at hand instead of thinking about application containers, frameworks, and other orchestration tools that are needed for full applications. AWS bills for each execution of the function by memory usage, length of time, and bandwidth.

The API Gateway from AWS allows developers to create web service apis that are capable of integrating with other web services or synchronously calling Lambda functions. The API Gateway taps into IAM so that developers can leverage granular security policies to secure the services.

Part 1 of this post will define how to configure the Lambda functions. Part 2 will define how to setup the API Gateway. Part 3 will describe how to configure security policies in IAM and deploy the API.

Configure the getContacts Lambda Functions

Go to the AWS Lambda console and select Create a Lambda Function. If this is your first time creating a function, select Get Started. AWS provides blueprints to help with defining basic project configuration. Search in the filter for hello-world. The hello-world blueprint defines a basic Node Lambda function.

Creating a new function

Set the name of the function to getContacts, add a meaningful description, and set the runtime to Node.js 4.3.

Creating a new function

Add the following code for this function. This function will receive an event object and context about the event.

'use strict';
         
/**
 * Returns the contact matching the id.  Otherwise it returns all contacts.
 */
exports.handler = function(event, context) {
  var id = event.id;
  var response;
  if(id === undefined) {
      console.log('Returning all contacts');
      //No id specified
      //Mock data
      response = [{
          id: 1,
          name: 'Adam Smith',
          phone: '555-555-5555',
          email: '[email protected]'
      },{
          id: 2,
          name: 'Rebecca Knox',
          phone: '222-222-2222',
          email: '[email protected]'
      }];
  } else {
      console.log('Returning contact with id ' + id);
      //Id specified
      //Mock data
      response = {
          id: id,
          name: 'Adam Smith',
          phone: '555-555-5555',
          email: '[email protected]'
      };
  }
  context.done(null, response);
};

Set the handler to index.handler which is the name of the javascript function that will be invoked. Set the role to Basic Execution Roll. This will open a new window that creates the role in the IAM console.

Creating a new function

IAM roll configuration

The advanced setting should not require modification but should have the following values.

Creating a new function

Select Next and confirm the function configuration.

Creating a new function

Now try testing your new Lambda getContacts function. Select Test and set an empty json object as the payload for the event.

Test the function

Save and test.

The response from the function call should be.

[
  {
    "id": 1,
    "name": "Adam Smith",
    "phone": "555-555-5555",
    "email": "[email protected]"
  },
  {
    "id": 2,
    "name": "Rebecca Knox",
    "phone": "222-222-2222",
    "email": "[email protected]"
  }
]

The resulting log output should be as follows.

START RequestId: a1116b24-2457-11e6-9570-111164491f16 Version: $LATEST
2016-05-27T22:09:10.633Z	a1116b24-2457-11e6-9570-111164491f16	Returning all contacts
END RequestId: a1116b24-2457-11e6-9570-111164491f16
REPORT RequestId: a1116b24-2457-11e6-9570-111164491f16	Duration: 0.40 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 37 MB	

Now test with an id set on the request object. Select Actions->Configure test event

Test the function

The response should return one object with the id you specified.

Configure the addContact Lambda Function

Now create a second Lambda function called addContact with the following code. All of the configuration should be the same as the last function.

'use strict';
         
/**
 * Creates a new contact.
 */
exports.handler = function(event, context) {
  var name = event.name;
  var phone = event.phone;
  var email = event.email;
  if(name === undefined) {
      context.done(new Error("Missing name value"));
      return;
  }
  var response = {
      id: 1,
      name: name,
      phone: phone,
      email: email
  };
  context.done(null, response);
};

Test the addContact function with an empty event object to verify that the error handling works as expected.

{
  "errorMessage": "Missing name value",
  "errorType": "Error",
  "stackTrace": [
    "exports.handler (/var/task/index.js:11:20)"
  ]
}

Now test with an event object containing a new contact. (note: you will need to modify your test input through Actions->Configure test event)

Event object:

{
    "name" : "Adam Smith",
    "phone" : "555-555-5555"
}

Function response:

{
  "id": 1,
  "name": "Adam Smith",
  "phone": "555-555-5555"
}

If both tests work then congratulations on creating your first Lambda functions. Part 2 of this post will describe how to configure these functions to run synchronously on an API Gateway HTTP request.