AWS: API-Gateway – Lambda proxy integration

Sometimes it might be more convinient to use ‘Lambda proxy integration’ to handle all requests.

The code below requires:

It means that we pass the whole request to lambda (with no posibility to enhance it) and we let lambda build the full response.

Let’s have a look how such handling might look like in Java code:

import static io.vavr.API.$;
import static io.vavr.API.Case;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.vavr.API;
import io.vavr.collection.Seq;
import io.vavr.control.Try;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

public class Lambda {

    private static final Logger log = LogManager.getLogger(Lambda.class);

    public APIGatewayProxyResponseEvent dispatchRequests(APIGatewayProxyRequestEvent requestEvent, Context context) throws JsonProcessingException {
        final APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();

        final Validation validationResult = validateRequest(requestEvent, API_VERSION);
        if (validationResult.isInvalid()) {
            return setStatusCodeAndBody(responseEvent, 400, validationResult.getError().toJavaList());

        final ApiRequestValidator.ApiRequest apiRequest = validationResult.get();
        final Try authorizationResult = authorize(apiRequest.getAuthorization());
        if (authorizationResult.isFailure()) {
            return setStatusCodeAndBody(responseEvent, 401, authorizationResult.getCause());

        // dispatch request
            Case($("/" + API_VERSION + "/resource"),              resourceHandler()),
            Case($("/" + API_VERSION + "/resource/sub-resource"), subResourceHandler()),
            Case($(), o -> {
                throw new UnsupportedEndpointException(o);
            .onSuccess(endpointResult -> setStatusCodeAndBody(responseEvent, 200, endpointResult))
            .onFailure(throwable -> setStatusCodeAndBody(responseEvent, 500, throwable.getLocalizedMessage()));

        return responseEvent;

    private Map defaultHeaders() {
        Map result = new HashMap();
        result.put("Content-Type", "application/json");
        result.put("Access-Control-Allow-Origin", "*");
        return result;

    private APIGatewayProxyResponseEvent setStatusCodeAndBody(APIGatewayProxyResponseEvent responseEvent, int statusCode, Object body) {
        setBody(responseEvent, body);
        return responseEvent;

    private Validation validateRequest(APIGatewayProxyRequestEvent event, String apiPrefix) {
        return new ApiRequestValidator(apiPrefix).validateRequest(event.getHeaders(), event.getPath(), event.getHttpMethod());


Code above introduces a few lines where:

  • status codes are set i.e. 200, 401, 500
  • ‘Content-Type’ or other flags are set in response’s header

Therefore, lambda takes full responsibility for handling the original requests that arrive at API-Gateway, than map the url path to specific controller to handle the logic, and at the end build a valid response.

In fact, there are not many things that API-Gateway can do….its role is simplified just to passing the requests and responses…

It can be easily noticed by looking at the API-Gataway’s proxy integration panel:


The ‘Integration’ parts are disabled or reduced with its functionality, while these parts are crucial when it comes to handling the requests and responses. Since we are using ‘lambda proxy integration’ we delegate the responsibily of handling the requests and response directly to lambda.

Below is the view of ‘Integration Request’ panel:


To set up the ‘lambda integration proxy’ read AWS documentation: