Set up Lambda custom integrations in API Gateway
To show how to set up the Lambda custom integration, we create an API Gateway API to expose
the GET /greeting?greeter={name}
method to invoke a Lambda function. The
function responds with a message of "Hello, {name}!"
if the
greeter
parameter value is a non-empty string. It returns a message of
"Hello, World!"
if the greeter
value is an empty string.
The function returns an error message of "Missing the required greeter
parameter."
if the greeter parameter is not set in the incoming request. We
name the function HelloWorld
.
For reference, a Node.js version of the Lambda function is shown as follows:
export const handler = function(event, context, callback) { var res ={ "statusCode": 200, "headers": { "Content-Type": "*/*" } }; if (event.greeter==null) { callback(new Error('Missing the required greeter parameter.')); } else if (event.greeter === "") { res.body = "Hello, World"; callback(null, res); } else { res.body = "Hello, " + event.greeter +"!"; callback(null, res); } };
You can create it in the Lambda console or by using the Amazon CLI. In this section, we reference this function using the following ARN:
arn:aws:lambda:us-east-1:123456789012:function:HelloWorld
With the Lambda function set in the backend, proceed to set up the API.
To set up the Lambda custom integration using the Amazon CLI
-
Call the
create-rest-api
command to create an API:aws apigateway create-rest-api --name 'HelloWorld (Amazon CLI)' --region us-west-2
Note the resulting API's
id
value (te6si5ach7
) in the response:{ "name": "HelloWorld (Amazon CLI)", "id": "te6si5ach7", "createdDate": 1508461860 }
You need the API
id
throughout this section. -
Call the
get-resources
command to get the root resourceid
:aws apigateway get-resources --rest-api-id te6si5ach7 --region us-west-2
The successful response is as follows:
{ "items": [ { "path": "/", "id": "krznpq9xpg" } ] }
Note the root resource
id
value (krznpq9xpg
). You need it in the next step and later. -
Call
create-resource
to create an API Gateway Resource of/greeting
:aws apigateway create-resource --rest-api-id te6si5ach7 \ --region us-west-2 \ --parent-id krznpq9xpg \ --path-part greeting
The successful response is similar to the following:
{ "path": "/greeting", "pathPart": "greeting", "id": "2jf6xt", "parentId": "krznpq9xpg" }
Note the resulting
greeting
resource'sid
value (2jf6xt
). You need it to create a method on the/greeting
resource in the next step. -
Call
put-method
to create an API method request ofGET /greeting?greeter={name}
:aws apigateway put-method --rest-api-id te6si5ach7 \ --region us-west-2 \ --resource-id 2jf6xt \ --http-method GET \ --authorization-type "NONE" \ --request-parameters method.request.querystring.greeter=false
The successful response is similar to the following:
{ "apiKeyRequired": false, "httpMethod": "GET", "authorizationType": "NONE", "requestParameters": { "method.request.querystring.greeter": false } }
This API method allows the client to receive a greeting from the Lambda function at the backend. The
greeter
parameter is optional because the backend should handle either an anonymous caller or a self-identified caller. -
Call
put-method-response
to set up the200 OK
response to the method request ofGET /greeting?greeter={name}
:aws apigateway put-method-response \ --region us-west-2 \ --rest-api-id te6si5ach7 \ --resource-id 2jf6xt \ --http-method GET \ --status-code 200
-
Call
put-integration
to set up the integration of theGET /greeting?greeter={name}
method with a Lambda function, namedHelloWorld
. The function responds to the request with a message of"Hello, {name}!"
, if thegreeter
parameter is provided, or"Hello, World!"
, if the query string parameter is not set.aws apigateway put-integration \ --region us-west-2 \ --rest-api-id te6si5ach7 \ --resource-id 2jf6xt \ --http-method GET \ --type Amazon \ --integration-http-method POST \ --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations \ --request-templates '{"application/json":"{\"greeter\":\"$input.params('greeter')\"}"}' \ --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
The mapping template supplied here translates the
greeter
query string parameter to thegreeter
property of the JSON payload. This is necessary because the input to a Lambda function must be expressed in the body.Important
For Lambda integrations, you must use the HTTP method of
POST
for the integration request, according to the specification of the Lambda service action for function invocations. Theuri
parameter is the ARN of the function-invoking action.Successful output is similar to the following:
{ "passthroughBehavior": "WHEN_NO_MATCH", "cacheKeyParameters": [], "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations", "httpMethod": "POST", "requestTemplates": { "application/json": "{\"greeter\":\"$input.params('greeter')\"}" }, "cacheNamespace": "krznpq9xpg", "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", "type": "AWS" }
The IAM role of
apigAwsProxyRole
must have policies that allow theapigateway
service to invoke Lambda functions. Instead of supplying an IAM role forcredentials
, you can call the add-permission command to add resource-based permissions. This is how the API Gateway console adds these permissions. -
Call
put-integration-response
to set up the integration response to pass the Lambda function output to the client as the200 OK
method response.aws apigateway put-integration-response \ --region us-west-2 \ --rest-api-id te6si5ach7 \ --resource-id 2jf6xt \ --http-method GET \ --status-code 200 \ --selection-pattern ""
By setting the selection-pattern to an empty string, the
200 OK
response is the default.The successful response should be similar to the following:
{ "selectionPattern": "", "statusCode": "200" }
-
Call
create-deployment
to deploy the API to atest
stage:aws apigateway create-deployment --rest-api-id te6si5ach7 --stage-name test --region us-west-2
-
Test the API using the following cURL command in a terminal:
curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=me' \ -H 'authorization: AWS4-HMAC-SHA256 Credential={access_key}/20171020/us-west-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f327...5751'