Amazon API Gateway
Developer Guide

TUTORIAL: Build a Hello World API with Lambda Proxy Integration

Lambda proxy integration is a lightweight, flexible API Gateway API integration type that allows you to integrate an API method – or an entire API – with a Lambda function. The Lambda function can be written in any language that Lambda supports. Because it's a proxy integration, you can change the Lambda function implementation at any time without needing to redeploy your API.

In this tutorial, you do the following:

  • Create a "Hello, World!" Lambda function to be the backend for the API.

  • Create and test a "Hello, World!" API with Lambda proxy integration.

Create a "Hello, World!" Lambda Function

This function returns a greeting to the caller as a JSON object in the following format:

{ "greeting": "Good {time}, {name} of {city}.[ Happy {day}!]" }

Create a "Hello, World!" Lambda function in the Lambda console

  1. Sign in to the Lambda console at

  2. On the AWS navigation bar, choose a region (for example, US East (N. Virginia)).


    Note the region where you create the Lambda function. You'll need it when you create the API.

  3. Choose Functions in the navigation pane.

  4. Choose Create function.

  5. Choose Author from scratch.

  6. Under Basic information, do the following:

    1. In Function name, enter GetStartedLambdaProxyIntegration.

    2. From the Runtime dropdown list, choose Node.js 8.10.

    3. From the Execution role dropdown list, choose Create new role from AWS policy templates.

    4. In Role name, enter GetStartedLambdaBasicExecutionRole.

    5. Leave the Policy templates field blank.

    6. Choose Create function.

  7. Under Function code, in the inline code editor, copy/paste the following code:

    'use strict'; console.log('Loading hello world function'); exports.handler = async (event) => { let name = "you"; let city = 'World'; let time = 'day'; let day = ''; let responseCode = 200; console.log("request: " + JSON.stringify(event)); if (event.queryStringParameters && { console.log("Received name: " +; name =; } if (event.queryStringParameters && { console.log("Received city: " +; city =; } if (event.headers && event.headers['day']) { console.log("Received day: " +; day =; } if (event.body) { let body = JSON.parse(event.body) if (body.time) time = body.time; } let greeting = `Good ${time}, ${name} of ${city}.`; if (day) greeting += ` Happy ${day}!`; let responseBody = { message: greeting, input: event }; // The output from a Lambda proxy integration must be // in the following JSON object. The 'headers' property // is for custom response headers in addition to standard // ones. The 'body' property must be a JSON string. For // base64-encoded payload, you must also set the 'isBase64Encoded' // property to 'true'. let response = { statusCode: responseCode, headers: { "x-custom-header" : "my custom header value" }, body: JSON.stringify(responseBody) }; console.log("response: " + JSON.stringify(response)) return response; };
  8. Choose Save.

Create a "Hello, World!" API

Now create an API for your "Hello, World!" Lambda function by using the API Gateway console.

Build a "Hello, World!" API

  1. Sign in to the API Gateway console at

  2. Create an empty API as follows:

    1. Choose Create API.

    2. Under Choose the protocol, choose REST.

    3. Under Create new API, choose New API.

    4. Under Settings:

      • For API name, enter LambdaSimpleProxy.

      • If desired, enter a description in the Description field; otherwise, leave it empty.

      • Leave Endpoint Type set to Regional.

    5. Choose Create API.

  3. Create the helloworld resource as follows:

    1. Choose the root resource (/) in the Resources tree.

    2. Choose Create Resource from the Actions dropdown menu.

    3. Leave Configure as proxy resource unchecked.

    4. For Resource Name, enter helloworld.

    5. Leave Resource Path set to /helloworld.

    6. Leave Enable API Gateway CORS unchecked.

    7. Choose Create Resource.

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

    1. In the Resources list, choose /helloworld.

    2. In the Actions menu, choose Create method.

    3. Choose ANY from the dropdown menu, and choose the checkmark icon

    4. Leave the Integration type set to Lambda Function.

    5. Choose Use Lambda Proxy integration.

    6. From the Lambda Region dropdown menu, choose the region where you created the GetStartedLambdaProxyIntegration Lambda function.

    7. In the Lambda Function field, type any character and choose GetStartedLambdaProxyIntegration from the dropdown menu.

    8. Leave Use Default Timeout checked.

    9. Choose Save.

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

Deploy and Test the API

Deploy the API in the API Gateway console

  1. Choose Deploy API from the Actions dropdown menu.

  2. For Deployment stage, choose [new stage].

  3. For Stage name, enter test.

  4. If desired, enter a Stage description.

  5. If desired, enter a Deployment description.

  6. Choose Deploy.

  7. Note the API's Invoke URL.

Use Browser and cURL to Test an API with Lambda Proxy Integration

You can use a browser or cURL to test your API.

To test GET requests using only query string parameters, you can type the URL for the API's helloworld resource into a browser address bar. For example:

For other methods, you must use more advanced REST API testing utilities, such as POSTMAN or cURL. This tutorial uses cURL. The cURL command examples below assume that cURL is installed on your computer.

To test the deployed API using cURL:

  1. Open a terminal window.

  2. Copy the following cURL command and paste it into the terminal window, replacing r275xc9bmd with your API's API ID and us-east-1 with the region where your API is deployed.

    curl -v -X POST \ '' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -d '{ "time": "evening" }'


    If you're running the command on Windows, use this syntax instead:

    curl -v -X POST "" -H "content-type: application/json" -H "day: Thursday" -d "{ \"time\": \"evening\" }"

You should get a successful response with a payload similar to the following:

{ "message":"Good evening, John of Seattle. Happy Thursday!", "input":{ "resource":"/helloworld", "path":"/helloworld", "httpMethod":"POST", "headers":{"Accept":"*/*", "content-type":"application/json", "day":"Thursday", "Host":"", "User-Agent":"curl/7.64.0""X-Amzn-Trace-Id":"Root=1-1a2b3c4d-a1b2c3d4e5f6a1b2c3d4e5f6", "X-Forwarded-For":"", "X-Forwarded-Port":"443", "X-Forwarded-Proto":"https"}, "multiValueHeaders":{"Accept":["*/*"]," content-type":["application/json"], "day":["Thursday"], "Host":[""], "User-Agent":["curl/0.0.0"], "X-Amzn-Trace-Id":["Root=1-1a2b3c4d-a1b2c3d4e5f6a1b2c3d4e5f6"], "X-Forwarded-For":["11.22.333.44"], "X-Forwarded-Port":["443"], "X-Forwarded-Proto":["https"]}, "queryStringParameters":{"city":"Seattle", "name":"John" }, "multiValueQueryStringParameters":{ "city":["Seattle"], "name":["John"] }, "pathParameters":null, "stageVariables":null, "requestContext":{ "resourceId":"3htbry", "resourcePath":"/helloworld", "htt* Connection #0 to host left intact pMethod":"POST", "extendedRequestId":"a1b2c3d4e5f6g7h=", "requestTime":"20/Mar/2019:20:38:30 +0000", "path":"/test/helloworld", "accountId":"123456789012", "protocol":"HTTP/1.1", "stage":"test", "domainPrefix":"r275xc9bmd", "requestTimeEpoch":1553114310423, "requestId":"test-invoke-request", "identity":{"cognitoIdentityPoolId":null, "accountId":null, "cognitoIdentityId":null, "caller":null, "sourceIp":"test-invoke-source-ip", "accessKey":null, "cognitoAuthenticationType":null, "cognitoAuthenticationProvider":null, "userArn":null, "userAgent":"curl/0.0.0","user":null }, "domainName":"", "apiId":"r275xc9bmd" }, "body":"{ \"time\": \"evening\" }", "isBase64Encoded":false } }

If you change POST to PUT in the preceding method request, you should get the same response.

To test the GET method, copy the following cURL command and paste it into the terminal window, replacing r275xc9bmd with your API's API ID and us-east-1 with the region where your API is deployed.

curl -X GET \ '' \ -H 'content-type: application/json' \ -H 'Day: Thursday'

You should get a response similar to the result from the preceding POST request, except that the GET request does not have any payload. So the body parameter will be null.

Java Version of the Backend Lambda Function

The following is a Java version of the "Hello, World!" Lambda function. To create this function in the Lambda console, you must create a deployment package before uploading the package into Lambda. For more information, see creating a deployment package in the AWS Lambda Developer Guide.

package examples; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import; import; import; import; import; public class Proxy implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { @Override public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) { LambdaLogger logger = context.getLogger(); logger.log("Loading Java Lambda handler of Proxy"); JSONParser parser = new JSONParser(); String name = "you"; String city = "World"; String time = "day"; String day = null; APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent(); try { Map<String, String> qps = event.getQueryStringParameters(); if (qps != null) { if (qps.get("name") != null) { name = qps.get("name"); } if (qps.get("city") != null) { city = qps.get("city"); } } Map<String, String> hps = event.getHeaders(); if (hps != null) { day = hps.get("Day"); } String bodyStr = event.getBody(); if (bodyStr != null) { JSONObject body; body = (JSONObject) parser.parse(bodyStr); if (body.get("time") != null) { time = (String) body.get("time"); } } String greeting = "Good " + time + ", " + name + " of " + city + "."; if (day != null && day != "") greeting += " Happy " + day + "!"; response.setHeaders(Collections.singletonMap("x-custom-header", "my custom header value")); response.setStatusCode(200); Map<String, String> responseBody = new HashMap<String, String>(); responseBody.put("input", event.toString()); responseBody.put("message", greeting); String responseBodyString = new JSONObject(responseBody).toJSONString(); response.setBody(responseBodyString); } catch (ParseException pex) { response.setStatusCode(400); Map<String, String> responseBody = Collections.singletonMap("message", pex.toString()); String responseBodyString = new JSONObject(responseBody).toJSONString(); response.setBody(responseBodyString); } logger.log(response.toString()); return response; } }