Over a million developers have joined DZone.

AWS Lambda With API Gateway

Check out how to update code for a deployed AWS Lambda, in addition to how to add a REST endpoint to it using AWS API Gateway.

· Cloud Zone

Download the Essential Cloud Buyer’s Guide to learn important factors to consider before selecting a provider as well as buying criteria to help you make the best decision for your infrastructure needs, brought to you in partnership with Internap.

In a previous post, I showed you how to create and deploy an AWS Lambda. We will continue that work and look at updating just the code for that lambda. We will also add a REST endpoint to the AWS Lambda using AWS API Gateway.

So before you continue... if you haven't already, please follow the instruction in the previous post to make sure you have a running AWS Lambda instance.

Step 1: Update Your Lambda

Paste the following in update-lambda.sh

#!/bin/bash

### Create the lambda package
zip -j helloworld.zip *.py

function_name="helloworld"
package_file=helloworld.zip

### Update the lambda code
aws lambda update-function-code \
  --function-name $function_name \
  --zip-file fileb://$package_file

Or for Java:

#!/bin/bash

### Create the lambda package
mvn package

function_name="helloworld"
package_file="target/lambda-java-example-1.0-SNAPSHOT.jar"

### Update the lambda code
aws lambda update-function-code \
   --function-name $function_name \
   --zip-file fileb://$package_file

Make the script executable chmod +x update-lambda.sh and update your lambda ./update-lambda.sh.

Step 2: Pass Something to Your Lambda

Now that we know how to update the lambda in the cloud, let's make a change so we can pass something as a parameter. Rather than saying "hello world!" we want it to say hello to whomever.

In Python:

def lambda_handler(event, context):
    return "Hello {}!".format(event['to'])

Or like the following in Java:

package example;

import com.amazonaws.services.lambda.runtime.Context;

public class Hello {
  public String lambdaHandler(Request request, Context context) {
    return "Hello " + request.getTo() + "!";
  }
}

class Request {
  private String to;
  public void setTo(String to) { this.to = to; }
  public String getTo() { return to; }
}

Step 3: Tell the Lambda to Say Hello to Whomever

aws lambda invoke --invocation-type RequestResponse --function-name helloworld --payload '{"to": "whomever"}' output.txt

You should see Hello whomever! in output text

Step 4: Let's Add the REST API

Paste the following script into a file such as create-api.sh, change permissions for the file to execute, and execute the script. Take a deep breath...

Note: this script expects the AWS_REGION and AWS_ACCOUNT_ID environment variables to be defined

#!/bin/bash
set -e

region=$AWS_REGION
account_id=$AWS_ACCOUNT_ID

echo "Creating a new API and capturing it's ID ..."
api_id=$(aws apigateway create-rest-api \
   --name HelloWorldAPI \
   --description "Hello World API" \
   --output text \
   --query 'id')
echo "> API ID is: $api_id"

echo "Storing the API ID on disk - we'll need it later ..."
echo $api_id > api_id.txt

echo "Geting the root resource id for the API ..."
root_id=$(aws apigateway get-resources \
   --rest-api-id "${api_id}" \
   --output text \
   --query 'items[?path==`'/'`].[id]')
echo root_id=$root_id

echo "Creating a resource for the /hello path"
resource_id=$(aws apigateway create-resource \
  --rest-api-id "${api_id}" \
  --parent-id "${root_id}" \
  --path-part hello | jq -r .id) 
echo "Resource id is $resource_id"

echo "Creating the GET method on the /hello resource"
aws apigateway put-method \
  --rest-api-id "${api_id}" \
  --resource-id "${resource_id}" \
  --http-method GET \
  --authorization-type NONE 

echo "Integrating the GET method to lambda. Note that the request tempalate uses API Gateway template language to pull in the query parameters as a JSON event for the lambda."
aws apigateway put-integration \
  --rest-api-id "${api_id}" \
  --resource-id "${resource_id}" \
  --http-method GET \
  --type AWS \
  --request-templates '{ "application/json": "{\n  #foreach($param in $input.params().querystring.keySet())\n    \"$param\": \"$util.escapeJavaScript($input.params().querystring.get($param))\" \n   #end\n  }" }' \
  --integration-http-method POST \
  --uri arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${region}:${account_id}:function:helloworld/invocations

echo "Creating a default response for the GET method"
aws apigateway put-method-response \
  --rest-api-id "${api_id}" \
  --resource-id "${resource_id}" \
  --http-method GET \
  --status-code 200 

echo "Creating a default response for the integration"
aws apigateway put-integration-response \
  --rest-api-id "${api_id}" \
  --resource-id "${resource_id}" \
  --http-method GET \
  --status-code 200 \
  --selection-pattern ".*"

echo "Adding permission for the API to call the lambda for test so we can use the console to make the api call"
aws lambda add-permission \
  --function-name helloworld \
  --statement-id apigateway-helloworld-get-test \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:${region}:${account_id}:${api_id}/*/GET/hello"

echo "Adding permission for the API to call the lambda from any HTTP client"
aws lambda add-permission \
  --function-name helloworld \
  --statement-id apigateway-helloworld-get \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:${region}:${account_id}:${api_id}/api/GET/hello"

echo "Creating a deployment"
aws apigateway create-deployment \
  --rest-api-id "${api_id}" \
  --stage-name api 

echo "All done! you can invoke the api on https://${api_id}.execute-api.${region}.amazonaws.com/api/hello?to=whomever"

Step 5: Invoke the API

The last output of the scripts provides the URL that you can paste into the browser. You should see the response "Hello whomever!" once you hit enter in the browser.

Step 6: The Cleanup

You can use the delete.sh script created in the previous post to delete the lambda. To delete the API: Paste the following script and execute as per usual.

#!/bin/bash
echo "Reading API id that I store in my create-api script"
api_id=$(<api_id.txt)

echo "Removing the permissions from the lambda"
aws lambda remove-permission \
  --function-name helloworld \
  --statement-id apigateway-helloworld-get
aws lambda remove-permission \
  --function-name helloworld \
  --statement-id apigateway-helloworld-get-test

echo "Deleting the API"
aws apigateway delete-rest-api \
  --rest-api-id "${api_id}"

Step 7: Relax... It's Over

... for now!

This article was first published on the Codurance blog.

The Cloud Zone is brought to you in partnership with Internap. Read Bare-Metal Cloud 101 to learn about bare-metal cloud and how it has emerged as a way to complement virtualized services.

Topics:
rest ,endpoint ,api ,aws ,lambda ,gateway

Published at DZone with permission of Mashooq Badar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}