Menu
Amazon API Gateway
Developer Guide

Create an API with Lambda Proxy Integration through a Proxy Resource

As a prerequisite, we create a Lambda function as the back end of our API through the Lambda proxy integration with a proxy resource. As an illustration, we will create the following Node.js function, named SimpleLambda4ProxyResource, using the AWS Lambda console.

We then create an API with the Lambda proxy integration by using the SimpleLambda4ProxyResource function through a proxy resource by using the API Gateway console. In conclusion, we demonstrate how to test the API.

A Lambda Function in Node.js for Proxy Integration

The following Lambda function in Node.js is a "Hello, World!" application. The function shows how to parse the input event parameter that contains a request made by a client to an API Gateway proxy resource. This resource is integrated with the function using the Lambda proxy integration. The function also demonstrates how to format the output of the Lambda function for API Gateway to return the results as an HTTP response. For more information about the input and output formats that this type of Lambda function must follow, see Input Format of a Lambda Function for Proxy Integration and Output Format of a Lambda Function for Proxy Integration.

Copy
'use strict'; console.log('Loading hello world function'); exports.handler = function(event, context, callback) { var name = "World"; var responseCode = 200; console.log("request: " + JSON.stringify(event)); if (event.queryStringParameters !== null && event.queryStringParameters !== undefined) { if (event.queryStringParameters.name !== undefined && event.queryStringParameters.name !== null && event.queryStringParameters.name !== "") { console.log("Received name: " + event.queryStringParameters.name); name = event.queryStringParameters.name; } if (event.queryStringParameters.httpStatus !== undefined && event.queryStringParameters.httpStatus !== null && event.queryStringParameters.httpStatus !== "") { console.log("Received http status: " + event.queryStringParameters.httpStatus); responseCode = event.queryStringParameters.httpStatus; } } var responseBody = { message: "Hello " + name + "!", input: event }; var response = { statusCode: responseCode, headers: { "x-custom-header" : "my custom header value" }, body: JSON.stringify(responseBody) }; console.log("response: " + JSON.stringify(response)) callback(null, response); };

When used with a proxy resource in API Gateway, the input parameter of event contains an API request marshalled as a JSON object by API Gateway. This input can include the request's HTTP method (httpMethod), path (path and pathParameters), query parameters (queryStringParameters), headers (headers), and applicable payload (body) as well as the context (requestContext) and stage variables (stageVariables).

This example Lambda function parses the event parameter to retrieve the query string parameters of name and httpStatus.

The function then returns a greeting to the named user in the message property of the responseBody object. To show the details of the incoming request as marshalled by API Gateway, the function also returns the incoming event object as the input property of the response body.

Finally, upon exiting, the function returns a JSON object, containing the required statusCode and any applicable headers and body, for API Gateway to return it as an HTTP response to the client.

A Lambda Function in Java for Proxy Integration

The following Lambda function in Java is a "Hello, World!" application, similar to its Node.js counterpart. The function shows how to parse the input event that is passed through as an InputStream object and that contains a request made by a client to an API Gateway proxy resource. This resource is integrated with the function using the Lambda proxy integration. It also shows how to parse the context object to get the LambdaLogger. The example also demonstrates how to format the output of the Lambda function for API Gateway in Java to return the results in an OutputStream object as an HTTP response. For more information about the Lambda proxy integration input and output formats, see Input Format of a Lambda Function for Proxy Integration and Output Format of a Lambda Function for Proxy Integration.

Copy
package examples; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.Writer; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import org.json.simple.JSONObject; import org.json.simple.JSONArray; import org.json.simple.parser.ParseException; import org.json.simple.parser.JSONParser; public class ProxyWithStream implements RequestStreamHandler { JSONParser parser = new JSONParser(); public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { LambdaLogger logger = context.getLogger(); logger.log("Loading Java Lambda handler of ProxyWithStream"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); JSONObject responseJson = new JSONObject(); String name = "World"; String responseCode = "200"; try { JSONObject event = (JSONObject)parser.parse(reader); if (event.get("queryStringParameters") != null) { JSONObject qps = (JSONObject)event.get("queryStringParameters"); if ( qps.get("name") != null) { name = (String)qps.get("name"); } if (qps.get("httpStatus") != null) { responseCode = qps.get("httpStatus)").toString(); } } JSONObject responseBody = new JSONObject(); responseBody.put("input", event.toJSONString()); responseBody.put("message", "Hello " + name + "!"); JSONObject headerJson = new JSONObject(); headerJson.put("x-custom-response-header", "my custom response header value"); responseJson.put("statusCode", responseCode); responseJson.put("headers", headerJson); responseJson.put("body", responseBody.toString()); } catch(ParseException pex) { responseJson.put("statusCode", "400"); responseJson.put("exception", pex); } logger.log(responseJson.toJSONString()); OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); writer.write(responseJson.toJSONString()); writer.close(); } }

When used with a proxy resource in API Gateway, the input stream contains an API request serialized as a JSON string by API Gateway. The input data can include the request's HTTP method (httpMethod), path (path and pathParameters), query parameters (queryStringParameters), headers (headers), applicable payload (body), the context (requestContext), and stage variables (stageVariables).

This example Lambda function parses the inputStream parameter to retrieve the query string parameters of name and httpStatus. For logging, it retrieves the LambdaLogger object from the incoming context object.

The function then returns a greeting to the named user in the message property of the responseBody object. To show the details of the incoming request as marshalled by API Gateway, the function also returns the input data (event) in the response body.

Finally, upon exiting, the function returns a JSON string, containing the required statusCode and any applicable headers and body, for API Gateway to return it as an HTTP response to the client.

To create this function in the Lambda console, you must create a deployment package before uploading the package into Lambda. To create a deployment package, follow these instructions.

Create a Back End for Lambda Proxy Integration

Now let's create the Lambda function in API Gateway using the Lambda console.

Create a Lambda function for an API with a proxy resource in the Lambda console

  1. Sign in to the Lambda console at https://console.aws.amazon.com/lambda.

  2. From the upper-right corner, choose an available region for the Lambda function.

  3. From the main navigation pane, choose Functions.

  4. Choose one of the following procedures to create a Lambda function in Node.js or Java. You can adapt the instructions for other languages and platforms.

    1. To create the Node.js Lambda function, choose Create a Lambda function or Get Started Now to create your first Lambda function in a region, and then do the following.

      1. On the Select blueprint page, choose Skip.

      2. On the Configure triggers page, choose Next.

      3. On the Configure function page, do the following:

        - Type a function name in the Name input field.

        - Type a brief function description in the Description input field.

        - From the Runtime drop-down list, choose Node.js 4.3.

      4. Under Lambda function code, do the following:

        - Choose Edit code inline from the Code entry type drop-down list.

        - Type or copy your Node.js code into the inline code editor.

      5. Under Lambda function handler and role, do the following:

        - Leave index.handler as-is for Handler.

        - Choose an existing or create a new IAM role for the function execution.

      6. Keep the default values for Advanced settings.

      7. Choose Next.

      8. In the Review pane, choose Create function.

      For this tutorial, use LambdaForSimpleProxy as the function name and choose the standard Simple Microservice permissions policy templates to create the required Lambda execution role.

    2. To create a Java Lambda function, choose Create a Lambda function or Get Started Now to create your first Lambda function in a region, and then do the following.

      1. On the Select blueprint page, choose Skip.

      2. On the Configure triggers page, choose Next.

      3. On the Configure function page, do the following:

        - Type a function name in the Name input field.

        - Type a brief function description in the Description input field.

        - From the Runtime drop-down list, choose Java 8.

      4. Under Lambda function code, do the following:

        - Choose a Code entry type for uploading a deployment package from a local drive or Amazon S3.

        - Choose Upload next to Function package.

        - Navigate to the deployment package location and select the package.

      5. Under Lambda function handler and role, do the following:

        - Type your function handler of the package_name.function_name::method_name format in Handler.

        - Choose an existing or create a new IAM role for the function execution.

      6. Keep the default values for Advanced settings.

      7. Choose Next.

      8. In the Review pane, choose Create function.

      For this tutorial, use examples as the Java package name, use ProxyWithStreams as the Java class name, use handleRequest as the Java function name, and use examples.ProxyWithStreams::handleRequest as the Lambda function handler name. Choose the standard Simple Microservice permissions policy templates to create the required Lambda execution role.

Note

Note the region where you created the Lambda function. You will need it when creating the API for the function.

Create API with Lambda Proxy Integration

Now create an API with a proxy resource for a Lambda function by using the API Gateway console.

Build an API with a proxy resource for a Lambda function

  1. Sign in to the API Gateway console at https://console.aws.amazon.com/apigateway.

  2. To create an API, choose Create new API (for creating the first API) or Create API (for creating any subsequent API). Next, do the following:

    1. Choose New API.

    2. Type a name in API Name .

    3. Optionally, add a brief description in Description.

    4. Choose Create API.

    For this tutorial, use LambdaSimpleProxy as the API name.

  3. To create a child resource, choose a parent resource item under the Resources tree and then choose Create Resource from the Actions drop-down menu. Then, do the following in the New Child Resource pane.

    1. Select the Configure as proxy resource option to create a proxy resource. Otherwise, leave it de-selected.

    2. Type a name in the Resource Name* input text field.

    3. Type a new name or use the default name in the Resource Path* input text field.

    4. Choose Create Resource.

    5. Select Enable API Gateway CORS, if required.

    For this tutorial, use the root resource (/) as the parent resource. Select Configure as proxy resource. For Resource Name, use the default, proxy. For Resource Path, use /{proxy+}. De-select Enable API Gateway CORS.

  4. To set up the ANY method for integration with the Lambda back end, do the following:

    1. Choose Lambda Function Proxy for Integration type.

    2. Choose a region from Lambda Region.

    3. Type the name of your Lambda function in Lambda Function.

    4. Choose Save.

    5. Choose OK when prompted with Add Permission to Lambda Function.

    For this tutorial, use the previously created LambdaForProxyResource for the Lambda Function.

For the proxy resource API that Lambda just created, API Gateway forwards the raw request from the client to the back end for the Lambda function to process. The request includes the request method, its path, query string and headers parameters, any payload, and context and stage variables. The next procedure describes how to test this.

Test API with Lambda Proxy Integration

The following procedure describes how to test the proxy integration.

Call the LambdaForProxyResource Lambda function through the proxy resource

  1. To use a browser to call a GET method on a specific resource of the API, do the following.

    1. If you have not done so, choose Deploy API from the Actions drop-down menu for the API you created. Follow the instructions to deploy the API to a specific stage. Note the Invoke URL that displays on the resulting Stage Editor page. This is the base URL of the API.

    2. To submit a GET request on a specific resource, append the resource path, including possible query string expressions to the Invoke URL value obtained in the previous step, copy the complete URL into the address bar of a browser, and choose Enter.

    For this tutorial, deploy the API to a test stage and append hello?name=me to the API's base URL to produce a URL of https://wt6mne2s9k.execute-api.us-west-2.amazonaws.com/test/hello?name=me.

    The successful response returns a result similar to the following output from the back-end Lambda function. The input property captures the raw request from API Gateway. The response contains httpMethod, path, headers, pathParameters, queryStringParameters, requestContext, and stageVariables.

    Copy
    { "message": "Hello me!", "input": { "path": "/test/hello", "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, lzma, sdch, br", "Accept-Language": "en-US,en;q=0.8", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "X-Forwarded-For": "192.168.100.1, 192.168.1.1", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "pathParameters": {"proxy": "hello"}, "requestContext": { "accountId": "123456789012", "resourceId": "us4z18", "stage": "test", "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "identity": { "cognitoIdentityPoolId": "", "accountId": "", "cognitoIdentityId": "", "caller": "", "apiKey": "", "sourceIp": "192.168.100.1", "cognitoAuthenticationType": "", "cognitoAuthenticationProvider": "", "userArn": "", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "user": "" }, "resourcePath": "/{proxy+}", "httpMethod": "GET", "apiId": "wt6mne2s9k" }, "resource": "/{proxy+}", "httpMethod": "GET", "queryStringParameters": {"name": "me"}, "stageVariables": {"stageVarName": "stageVarValue"} } }

    You can use a different proxy resource path of /hello/world?name=me to call the Lambda function. The input.path property value of the JSON payload of the successful response will become test/hello/world.

    If you use POST for the ANY method instead, the input property of the response payload contains a body JSON property. To test a POST request, you can use the API Gateway console TestInvoke feature, a Curl command, the Postman extension, or an AWS SDK.

  2. To use the API Gateway console to test invoking the API, do the following.

    1. Choose ANY on a proxy resource in the Resources tree.

    2. Choose Test in the Method Execution pane.

    3. From the Method drop-down list, choose an HTTP verb supported by the back end.

    4. Under Path, type a specific path for the proxy resource supporting the chosen operation.

    5. If required, type a supported query expression for the chosen operation under the Query Strings heading.

    6. If required, type one or more supported header expressions for the chosen operation under the Headers heading.

    7. If configured, set the required stage variable values for the chosen operation under the Stage Variables heading.

    8. If prompted and required, choose an API Gateway-generated client certificate under the Client Certificate heading to the operation to be authenticated by the back end.

    9. If prompted, type an appropriate request body in the text editor under the Request Body heading.

    10. Choose Test to test invoking the method.

    For this tutorial, use GET as the HTTP method, hello as the proxy resource path of {proxy}, and name=me as the query expression.

    The successful response will return a JSON payload that is similar to the payload shown in the previous step.