

# API Gateway의 REST API에 대한 Lambda 통합
<a name="set-up-lambda-integrations"></a>

 Lambda 프록시 통합 또는 Lambda 비프록시(사용자 지정) 통합을 사용하여 API 메서드를 Lambda 함수와 통합할 수 있습니다.

Lambda 프록시 통합에서는 필요한 설정이 간단합니다. 통합의 HTTP 메서드를 POST로, 통합 엔드포인트 URI를 특정 Lambda 함수의 Lambda 함수 호출 작업의 ARN으로 설정하고, 사용자를 대신해 Lambda 함수를 호출할 수 있는 API Gateway 권한을 부여합니다.

Lambda 비 프록시 통합에서는, 프록시 통합 설정 단계 외에도 수신 요청 데이터가 통합 요청에 매핑되는 방식과 그 결과로 얻는 통합 응답 데이터가 메서드 응답에 매핑되는 방식도 지정합니다.

**Topics**
+ [API Gateway의 Lambda 프록시 통합](set-up-lambda-proxy-integrations.md)
+ [API Gateway에서 Lambda 사용자 지정 통합 설정](set-up-lambda-custom-integrations.md)
+ [백엔드 Lambda 함수의 비동기 호출 설정](set-up-lambda-integration-async.md)
+ [API Gateway에서 Lambda 오류 처리](handle-errors-in-lambda-integration.md)

# API Gateway의 Lambda 프록시 통합
<a name="set-up-lambda-proxy-integrations"></a>

다음 섹션에서는 Lambda 프록시 통합을 사용하는 방법을 보여줍니다.

**Topics**
+ [API Gateway Lambda 프록시 통합 이해](#api-gateway-create-api-as-simple-proxy)
+ [다중 값 헤더 및 쿼리 문자열 파라미터에 대한 지원](#apigateway-multivalue-headers-and-parameters)
+ [프록시 통합에 대한 Lambda 함수의 입력 형식](#api-gateway-simple-proxy-for-lambda-input-format)
+ [프록시 통합에 대한 Lambda 함수의 출력 형식](#api-gateway-simple-proxy-for-lambda-output-format)
+ [AWS CLI를 사용하여 API Gateway용 Lambda 프록시 통합 설정](set-up-lambda-proxy-integration-using-cli.md)
+ [OpenAPI 정의와 Lambda 프록시 통합을 사용하여 프록시 리소스 설정](api-gateway-set-up-lambda-proxy-integration-on-proxy-resource.md)

## API Gateway Lambda 프록시 통합 이해
<a name="api-gateway-create-api-as-simple-proxy"></a>

Amazon API Gateway의 Lambda 프록시 통합은 단일 API 메서드의 설정을 통해 API를 구축하기 위한 간단하고 강력하며 민첩한 메커니즘입니다. Lambda 프록시 통합을 사용하면 클라이언트가 백엔드에서 단일 Lambda 함수를 호출할 수 있습니다. 이 함수는 다른 Lambda 함수를 호출하는 등 다른 AWS 서비스의 많은 리소스 또는 기능에 액세스합니다.

 Lambda 프록시 통합에서 클라이언트가 API 요청을 제출하면 API Gateway는 통합된 Lambda 함수로 [이벤트 객체](#api-gateway-simple-proxy-for-lambda-input-format)를 전달합니다. 단, 요청 파라미터의 순서는 유지되지 않습니다. [요청 데이터](#api-gateway-simple-proxy-for-lambda-input-format)에는 요청 헤더, 쿼리 문자열 파라미터, URL 경로 변수, 페이로드 및 API 구성 데이터가 포함되어 있습니다. 구성 데이터에는 현재 배포 단계 이름, 단계 변수, 사용자 ID 또는 권한 부여 컨텍스트(있는 경우)가 포함될 수 있습니다. 백엔드 Lambda 함수는 수신되는 요청 데이터를 구문 분석하여 반환하는 응답을 결정합니다. API Gateway에서 Lambda 출력을 클라이언트에 대한 API 응답으로 전달하려면 Lambda 함수에서 [이 형식](#api-gateway-simple-proxy-for-lambda-output-format)으로 결과를 반환해야 합니다.

 API Gateway는 Lambda 프록시 통합을 위해 클라이언트와 백엔드 Lambda 함수 사이에 개입하지 않기 때문에 클라이언트와 통합된 Lambda 함수는 API의 기존 통합 설정을 깨지 않고 서로의 변화에 맞게 조정할 수 있습니다. 이렇게 하려면 클라이언트가 백엔드 Lambda 함수에 의해 제정된 애플리케이션 프로토콜을 따라야 합니다.

 모든 API 메서드에 대해 Lambda 프록시 통합을 설정할 수 있습니다. 그러나 Lambda 프록시 통합은 일반 프록시 리소스가 포함된 API 메서드에 대해 구성될 때 더 강력합니다. 일반 프록시 리소스는 `{proxy+}`의 특수 템플릿 경로 변수, catch-all `ANY` 메서드 자리 표시자 또는 둘 다로 표시될 수 있습니다. 클라이언트는 수신되는 요청의 백엔드 Lambda 함수에 대한 입력을 요청 파라미터 또는 해당 페이로드로 전달할 수 있습니다. 요청 파라미터에는 헤더, URL 경로 변수, 쿼리 문자열 파라미터 및 해당 페이로드가 포함되어 있습니다. 통합된 Lambda 함수는 필요한 입력이 누락된 경우 요청을 처리하고 의미 있는 오류 메시지로 클라이언트에 응답하기 전에 모든 입력 소스를 확인합니다.

 일반 HTTP 메서드 `ANY` 및 일반 리소스 `{proxy+}`와 통합된 API 메서드를 호출할 때 클라이언트는 `ANY` 대신 특정 HTTP 메서드를 사용하여 요청을 제출합니다. 또한 클라이언트는 `{proxy+}` 대신 특정 URL 경로를 지정하고 필수 헤더, 쿼리 문자열 파라미터 또는 해당 페이로드를 포함합니다.

 다음 목록에는 Lambda 프록시 통합을 통해 다양한 API 메서드의 런타임 동작이 요약되어 있습니다.
+ `ANY /{proxy+}`: 클라이언트는 특정 HTTP 메서드를 선택하고 특정 리소스 경로 계층을 설정해야 하며 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.
+ `ANY /res`: 클라이언트는 특정 HTTP 메서드를 선택해야 하고 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.
+ `GET|POST|PUT|... /{proxy+}`: 클라이언트는 특정 리소스 경로 계층, 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.
+  `GET|POST|PUT|... /res/{path}/...`: 클라이언트는 특정 경로 세그먼트(`{path}` 변수의 경우)를 선택해야 하고 요청 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 입력 데이터를 통합된 Lambda 함수에 전달할 수 있습니다.
+  `GET|POST|PUT|... /res`: 클라이언트는 요청 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 선택하여 입력 데이터를 통합된 Lambda 함수에 전달할 수 있습니다.

 프록시 리소스 `{proxy+}` 및 사용자 지정 리소스 `{custom}` 모두 템플릿 경로 변수로 표현됩니다. 그러나 `{proxy+}`는 경로 계층을 따라 모든 리소스를 참조할 수 있지만 `{custom}`은 특정 경로 세그먼트만 참조합니다. 예를 들어 식품 매장은 부서 이름, 생산 카테고리 및 제품 유형별로 온라인 제품 재고를 구성할 수 있습니다. 식품 매장의 웹 사이트는 사용자 지정 리소스의 템플릿 경로 변수인 `/{department}/{produce-category}/{product-type}`을 사용하여 사용 가능한 제품을 나타낼 수 있습니다. 예를 들어 사과는 `/produce/fruit/apple`로, 당근은 `/produce/vegetables/carrot`으로 표현됩니다. 또한 `/{proxy+}`를 사용하여 온라인 매장에서 쇼핑하는 동안 고객이 검색할 수 있는 부서, 생산 카테고리 또는 제품 유형을 나타낼 수 있습니다. 예를 들어 `/{proxy+}`는 다음 항목 중 하나를 참조할 수 있습니다.
+ `/produce`
+ `/produce/fruit`
+ `/produce/vegetables/carrot`

 고객이 사용 가능한 제품, 제품 카테고리 및 관련 매장 부서를 검색할 수 있게 하려면 읽기 전용 권한으로 `GET /{proxy+}`의 단일 메서드를 공개할 수 있습니다. 마찬가지로 감독자가 `produce` 부서의 재고를 업데이트할 수 있게 하려면 읽기/쓰기 권한으로 `PUT /produce/{proxy+}`의 또 다른 단일 메서드를 설정할 수 있습니다. 점원이 야채의 총 누계를 업데이트할 수 있게 하려면 읽기/쓰기 권한으로 `POST /produce/vegetables/{proxy+}` 메서드를 설정할 수 있습니다. 매장 관리자가 사용 가능한 제품에 대해 가능한 조치를 수행할 수 있게 하려면 온라인 매장 개발자는 읽기/쓰기 권한으로 `ANY /{proxy+}` 메서드를 공개할 수 있습니다. 어떤 경우에도 런타임 시 고객 또는 직원은 선택한 부서에서 지정된 유형의 특정 제품, 선택한 부서의 특정 생산 카테고리 또는 특정 부서를 선택해야 합니다.



API Gateway 프록시 통합 설정에 대한 자세한 내용은 [프록시 리소스를 사용하여 프록시 통합 설정](api-gateway-set-up-simple-proxy.md)를 참조하세요.

 프록시 통합을 위해서는 클라이언트가 백엔드 요구 사항에 대해 보다 자세한 지식을 갖추고 있어야 합니다. 따라서 최적의 앱 성능과 사용자 경험을 보장하려면 백엔드 개발자는 클라이언트 개발자에게 백엔드 요구 사항을 명확하게 전달하고 요구 사항이 충족되지 않으면 강력한 오류 피드백 메커니즘을 제공해야 합니다.

## 다중 값 헤더 및 쿼리 문자열 파라미터에 대한 지원
<a name="apigateway-multivalue-headers-and-parameters"></a>

API Gateway는 이제 동일한 이름을 지닌 복수의 헤더 및 쿼리 문자열 파라미터를 지원합니다. 다중 값 헤더와 단일 값 헤더 및 파라미터는 동일한 요청 및 응답에서 결합될 수 있습니다. 자세한 내용은 [프록시 통합에 대한 Lambda 함수의 입력 형식](#api-gateway-simple-proxy-for-lambda-input-format) 및 [프록시 통합에 대한 Lambda 함수의 출력 형식](#api-gateway-simple-proxy-for-lambda-output-format)(을)를 참조하세요.

## 프록시 통합에 대한 Lambda 함수의 입력 형식
<a name="api-gateway-simple-proxy-for-lambda-input-format"></a>

Lambda 프록시 통합을 사용할 경우 API Gateway에서 전체 클라이언트 요청을 백엔드 Lambda 함수의 입력 `event` 파라미터에 매핑합니다. 다음 예제에서는 API Gateway가 Lambda 프록시 통합으로 보내는 이벤트의 구조를 보여줍니다.

이 예제에서는 API Gateway에 대한 간접 호출이 다음과 같다고 가정합니다.

```
curl 'https://a1b2c3.execute-api.us-east-1.amazonaws.com/my/path?parameter1=value1&parameter2=value1&parameter2=value2&parameter3=value1,value2' -H 'header1: value1' -H 'header2: value1' -H 'header2: value2' -H 'header3: value1,value2'
```

출력은 다음과 같습니다.

```
{
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
      "header1": "value1",
      "header2": "value2",
      "header3": "value1,value2"
  },
  "multiValueHeaders": {
    "header1": ["value1"],
    "header2": ["value1","value2"],
    "header3": ["value1,value2"]
  },
  "queryStringParameters": {
      "parameter1": "value1",
      "parameter2": "value2",
      "parameter3": "value1,value2"
  },
  "multiValueQueryStringParameters": {
    "parameter1": ["value1"],
    "parameter2": ["value1","value2"],
    "parameter3": ["value1,value2"]
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "id",
    "authorizer": {
      "claims": null,
      "scopes": null
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "extendedRequestId": "request-id",
    "httpMethod": "GET",
    "identity": {
      "accessKey": null,
      "accountId": null,
      "caller": null,
      "cognitoAuthenticationProvider": null,
      "cognitoAuthenticationType": null,
      "cognitoIdentityId": null,
      "cognitoIdentityPoolId": null,
      "principalOrgId": null,
      "sourceIp": "IP",
      "user": null,
      "userAgent": "user-agent",
      "userArn": null,
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "path": "/my/path",
    "protocol": "HTTP/1.1",
    "requestId": "id=",
    "requestTime": "04/Mar/2020:19:15:17 +0000",
    "requestTimeEpoch": 1583349317135,
    "resourceId": null,
    "resourcePath": "/my/path",
    "stage": "$default"
  },
  "pathParameters": null,
  "stageVariables": null,
  "body": "Hello from Lambda!",
  "isBase64Encoded": false
}
```

**참고**  
입력에서:  
`headers` 키에는 단일 값 헤더만 있습니다.
`multiValueHeaders` 키에는 다중 값 헤더와 단일 값 헤더가 있을 수 있습니다.
`headers` 및 `multiValueHeaders` 모두에 대해 값을 지정한 경우, API Gateway는 이들 헤더를 단일 목록으로 병합합니다. 동일한 키-값 페어가 양쪽 모두에 지정된 경우, `multiValueHeaders`의 값만이 병합된 목록에 표시됩니다.

백엔드 Lambda 함수에 대한 입력에서 `requestContext` 객체는 키-값 페어의 맵입니다. 각 페어에서 키는 [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) 변수 속성의 이름이고, 값은 그 속성의 값입니다. API Gateway는 새 키를 맵에 추가할 수 있습니다.

활성화된 기능에 따라 `requestContext` 맵은 API마다 다를 수 있습니다. 예를 들어 앞의 예제에서는 권한 부여 유형이 지정되지 않았으므로 `$context.authorizer.*` 또는 `$context.identity.*` 속성이 없습니다. 권한 부여 유형이 지정된 경우에는 다음과 같이 API Gateway가 `requestContext.identity` 객체의 통합 엔드포인트에 권한이 부여된 사용자 정보를 전달합니다.
+ 권한 부여 유형이 `AWS_IAM`인 경우, 권한 부여된 사용자 정보에 `$context.identity.*` 속성이 포함됩니다.
+ 권한 부여 유형이 `COGNITO_USER_POOLS`(Amazon Cognito 권한 부여자)인 경우, 권한 부여된 사용자 정보에 `$context.identity.cognito*` 및 `$context.authorizer.claims.*` 속성이 포함됩니다.
+ 권한 부여 유형이 `CUSTOM`(Lambda 권한 부여자)인 경우, 권한 부여된 사용자 정보에 `$context.authorizer.principalId` 및 기타 적용되는 `$context.authorizer.*` 속성이 포함됩니다.

## 프록시 통합에 대한 Lambda 함수의 출력 형식
<a name="api-gateway-simple-proxy-for-lambda-output-format"></a>

Lambda 프록시 통합을 사용할 경우 API Gateway에서는 백엔드 Lambda 함수에 다음 JSON 형식에 따라 출력을 반환하도록 요구합니다.

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..."
}
```

출력에서:
+ 출력에서 추가 응답 헤더가 반환되지 않을 경우 `headers` 및 `multiValueHeaders` 키가 비지정 상태일 수 있습니다.
+ `headers` 키에는 단일 값 헤더만 있습니다.
+ `multiValueHeaders` 키에는 다중 값 헤더와 단일 값 헤더가 있을 수 있습니다. `multiValueHeaders` 키를 사용하여 모든 단일 값 헤더를 포함하는 모든 추가 헤더를 지정할 수 있습니다.
+ `headers` 및 `multiValueHeaders` 모두에 대해 값을 지정한 경우, API Gateway는 이들 헤더를 단일 목록으로 병합합니다. 동일한 키-값 페어가 양쪽 모두에 지정된 경우, `multiValueHeaders`의 값만이 병합된 목록에 표시됩니다.

Lambda 프록시 통합에 대해 CORS를 활성화하려면 출력 `Access-Control-Allow-Origin:domain-name`에 `headers`을 추가해야 합니다. `domain-name`은 모든 도메인 이름에 대해 `*`일 수 있습니다. 출력 `body`는 프런트엔드에 메서드 응답 페이로드로 마샬링됩니다. `body`가 이진 BLOB인 경우 `isBase64Encoded`를 `true`으로 설정하고, **이진 미디어 유형**을 `*/*`로 구성하여 Base64로 인코딩된 문자열로 인코딩할 수 있습니다. 그렇지 않은 경우 `false`로 설정하거나 지정되지 않은 상태로 둘 수 있습니다.

**참고**  
이진 지원 활성화에 대한 자세한 내용은 [API Gateway 콘솔을 사용하여 이진 지원 활성화](api-gateway-payload-encodings-configure-with-console.md) 단원을 참조하세요. Lambda 함수의 예는 [API Gateway의 Lambda 프록시 통합에서 이진 미디어 반환](lambda-proxy-binary-media.md) 단원을 참조하세요.

함수 출력의 형식이 다른 경우 API Gateway에서는 `502 Bad Gateway` 오류 응답을 반환합니다.

Node.js에서 Lambda 함수의 응답을 반환하려면 다음과 같은 명령어를 사용할 수 있습니다.
+ 성공 결과를 반환하려면 `callback(null, {"statusCode": 200, "body": "results"})`을 호출합니다.
+ 예외를 발생하려면 `callback(new Error('internal server error'))`를 호출합니다.
+ 클라이언트 측 오류의 경우(예: 필요한 파라미터가 없는 경우) `callback(null, {"statusCode": 400, "body": "Missing parameters of ..."})`를 호출하여 예외를 발생하지 않고 오류를 반환할 수 있습니다.

Node.js의 Lambda `async` 함수에서 이와 동일한 구문은 다음과 같습니다.
+ 성공 결과를 반환하려면 `return {"statusCode": 200, "body": "results"}`을 호출합니다.
+ 예외를 발생하려면 `throw new Error("internal server error")`를 호출합니다.
+ 클라이언트 측 오류의 경우(예: 필요한 파라미터가 없는 경우) `return {"statusCode": 400, "body": "Missing parameters of ..."}`를 호출하여 예외를 발생하지 않고 오류를 반환할 수 있습니다.

# AWS CLI를 사용하여 API Gateway용 Lambda 프록시 통합 설정
<a name="set-up-lambda-proxy-integration-using-cli"></a>

이 섹션에서는 AWS CLI를 사용하여 Lambda 프록시 통합으로 API를 설정하는 방법을 보여줍니다. API Gateway 콘솔을 사용하여 Lambda 프록시 통합을 통해 프록시 리소스를 구성하는 방법에 대한 자세한 내용은 [자습서: Lambda 프록시 통합을 통해 REST API 생성](api-gateway-create-api-as-simple-proxy-for-lambda.md) 단원을 참조하세요.

예를 들면 다음과 같은 샘플 Lambda 함수를 API의 백엔드로 사용합니다.

```
export const handler = async(event, context) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var res ={
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    };
    var greeter = 'World';
    if (event.greeter && event.greeter!=="") {
        greeter =  event.greeter;
    } else if (event.body && event.body !== "") {
        var body = JSON.parse(event.body);
        if (body.greeter && body.greeter !== "") {
            greeter = body.greeter;
        }
    } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
        greeter = event.queryStringParameters.greeter;
    } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
        greeter = event.multiValueHeaders.greeter.join(" and ");
    } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
        greeter = event.headers.greeter;
    } 
    res.body = "Hello, " + greeter + "!";
    return res
};
```

이를 [API Gateway에서 Lambda 사용자 지정 통합 설정](set-up-lambda-custom-integrations.md)의 Lambda 사용자 지정 통합 설정과 비교하여 이 Lambda 함수에 대한 입력을 요청 파라미터 및 본문으로 표현할 수 있습니다. 클라이언트가 동일한 입력 데이터를 전달하도록 허용하는 더 많은 위도가 있습니다. 여기에서 클라이언트는 greeter의 이름을 쿼리 문자열 파라미터, 헤더 또는 본문 속성으로 전달할 수 있습니다. 함수는 Lambda 사용자 지정 통합도 지원합니다. API 설정은 더 간단합니다. 메서드 응답 또는 통합 응답은 전혀 구성하지 않습니다.

**AWS CLI를 사용하여 Lambda 프록시 통합 설정**

1. 다음 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 명령을 사용하면 API를 생성할 수 있습니다.

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   출력은 다음과 같습니다.

   ```
   {
       "name": "HelloWorldProxy (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   이 예제에서는 API `id`(`te6si5ach7`)와 `rootResourceId`(`krznpq9xpg`)를 사용합니다.

1. 다음 [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 명령을 사용하면 `/greeting`의 API Gateway [리소스](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)를 생성할 수 있습니다.

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part {proxy+}
   ```

   출력은 다음과 같습니다.

   ```
   {
       "path": "/{proxy+}", 
       "pathPart": "{proxy+}", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   다음 단계에서는 `{proxy+}` 리소스의 `id` 값(`2jf6xt`)을 사용하여 `/{proxy+}` 리소스에 대한 메서드를 생성합니다.

1. 다음 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html)를 사용하면 `ANY /{proxy+}`의 `ANY` 메서드 요청을 생성할 수 있습니다.

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method ANY \
          --authorization-type "NONE"
   ```

   출력은 다음과 같습니다.

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "ANY", 
       "authorizationType": "NONE"
   }
   ```

   이 API 메서드를 통해 클라이언트는 백엔드에서 Lambda 함수의 인사를 수신 또는 발신할 수 있습니다.

1. 다음 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 명령을 사용하면 `HelloWorld`라는 Lambda 함수와 `ANY /{proxy+}` 메서드의 통합을 설정할 수 있습니다. 이 함수는 `"Hello, {name}!"` 파라미터가 제공되면 `greeter`이라는 메시지로, 쿼리 문자열 파라미터가 설정되어 있지 않으면 `"Hello, World!"`라는 메시지로 요청에 응답합니다.

   ```
   aws apigateway put-integration \
         --rest-api-id te6si5ach7 \
         --resource-id 2jf6xt \
         --http-method ANY \
         --type AWS_PROXY \
         --integration-http-method POST \
         --uri arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:HelloWorld/invocations \
         --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```
**중요**  
Lambda 통합의 경우에는 [함수 호출을 위한 Lambda 서비스 작업의 사양](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)에 따라 통합 요청에 대해 `POST`의 HTTP 메서드를 사용해야 합니다. `apigAwsProxyRole`의 IAM 역할에는 `apigateway` 서비스가 Lambda 함수를 호출하도록 허용하는 정책이 있어야 합니다. IAM 권한에 대한 자세한 내용은 [API 호출을 위한 API Gateway 권한 모델](permissions.md#api-gateway-control-access-iam-permissions-model-for-calling-api) 단원을 참조하세요.

   출력은 다음과 같습니다.

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:1234567890:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "cacheNamespace": "vvom7n", 
       "credentials": "arn:aws:iam::1234567890:role/apigAwsProxyRole", 
       "type": "AWS_PROXY"
   }
   ```

   `credentials`에 IAM 역할을 제공하는 대신 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 명령을 사용하여 리소스 기반 권한을 추가할 수 있습니다. 이 작업은 API Gateway 콘솔이 수행합니다.

1. 다음 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 명령을 사용하면 API를 `test` 스테이지에 배포할 수 있습니다.

   ```
   aws apigateway create-deployment  \
         --rest-api-id te6si5ach7 \
         --stage-name test
   ```

1. 터미널에서 다음 cURL 명령을 사용하여 API를 테스트합니다.

   `?greeter=jane`이라는 쿼리 문자열 파라미터와 함께 API를 호출:

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=jane'
   ```

   `greeter:jane`이라는 헤더 파라미터와 함께 API를 호출:

   ```
   curl -X GET https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -H 'greeter: jane'
   ```

   `{"greeter":"jane"}`이라는 본문과 함께 API를 호출:

   ```
   curl -X POST https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -d '{ "greeter": "jane" }'
   ```

   이 모든 경우에 출력되는 것은 다음과 같은 응답 본문이 있는 200 응답입니다.

   ```
   Hello, jane!
   ```

# OpenAPI 정의와 Lambda 프록시 통합을 사용하여 프록시 리소스 설정
<a name="api-gateway-set-up-lambda-proxy-integration-on-proxy-resource"></a>

Lambda 프록시 통합 유형을 사용하여 프록시 리소스를 설정하려면 복잡한 경로 파라미터(예: `/parent/{proxy+}`)를 사용하여 API 리소스를 생성한 후 이 리소스를 `arn:aws:lambda:us-west-2:123456789012:function:SimpleLambda4ProxyResource` 메서드의 Lambda 함수 백엔드(예: `ANY`)와 통합합니다. 복잡한 경로 파라미터는 API 리소스 경로의 끝에 와야 합니다. 비 프록시 리소스를 사용할 때와 마찬가지로 API Gateway 콘솔을 사용하거나 OpenAPI 정의 파일을 가져오거나 API Gateway REST API를 직접 호출하여 프록시 리소스를 설정할 수 있습니다.

다음 OpenAPI API 정의 파일은 `SimpleLambda4ProxyResource`라는 Lambda 함수에 통합된 프록시 리소스를 포함하는 API의 예를 보여줍니다.

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T17:50:37Z",
      "title": "ProxyIntegrationWithLambda"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "POST",
               "cacheNamespace": "roq9wj",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "aws_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://gy415nuibc.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/testStage"
            }
         }
      }
   ]
}
```

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T17:50:37Z",
    "title": "ProxyIntegrationWithLambda"
  },
  "host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
  "basePath": "/testStage",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "cacheNamespace": "roq9wj",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "aws_proxy"
        }
      }
    }
  }
}
```

------

Lambda 프록시 통합을 사용하여 API Gateway에서는 런타임에 수신 요청을 Lambda 함수의 입력 `event` 파라미터에 매핑합니다. 입력에는 요청 메서드, 경로, 헤더, 쿼리 문자열 파라미터, 페이로드, 연결된 컨텍스트, 정의된 단계 변수 등이 포함됩니다. 입력 형식에 대한 설명은 [프록시 통합에 대한 Lambda 함수의 입력 형식](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format) 단원을 참조하세요. API Gateway에서 Lambda 출력을 HTTP 응답에 성공적으로 매핑하도록 하려면 Lambda 함수에서 [프록시 통합에 대한 Lambda 함수의 출력 형식](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format)에 설명된 형식으로 결과를 출력해야 합니다.

`ANY` 메서드를 통한 프록시 리소스의 Lambda 프록시 통합에서는 단일 백엔드 Lambda 함수가 프록시 리소스를 통해 모든 요청에 대한 이벤트 핸들러 역할을 합니다. 예를 들어 트래픽 패턴을 기록하려면 프록시 리소스에 대한 URL 경로에 `/state/city/street/house`를 포함하는 요청을 제출하여 모바일 디바이스에서 시/도, 시, 거리, 빌딩 등 위치 정보를 전송하도록 할 수 있습니다. 그러면 백엔드 Lambda 함수에서 URL 경로를 구문 분석한 다음 위치 튜플을 DynamoDB 테이블에 삽입할 수 있습니다.

# API Gateway에서 Lambda 사용자 지정 통합 설정
<a name="set-up-lambda-custom-integrations"></a>

 Lambda 사용자 지정, 비프록시, 통합을 설정하는 방법을 보여주기 위해 API Gateway API를 만들어 Lambda 함수를 호출할 `GET /greeting?greeter={name}` 메서드를 공개합니다. 다음 예시 Lambda 함수 중 하나를 API에 사용하십시오.

다음 예시 Lambda 함수 중 하나를 사용하십시오.

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return greeting;
};
```

------
#### [ Python ]

```
import json


def lambda_handler(event, context):
    print(event)
    res = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    }

    if event['greeter'] == "":
        res['body'] = "Hello, World"
    elif (event['greeter']):
        res['body'] = "Hello, " + event['greeter'] + "!"
    else:
        raise Exception('Missing the required greeter parameter.')

    return res
```

------

이 함수는 `"Hello, {name}!"` 파라미터 값이 비어 있지 않은 문자열인 경우 `greeter`이라는 메시지로 응답합니다. `"Hello, World!"` 값이 빈 문자열이면 `greeter`라는 메시지를 반환합니다. 수신 요청에 greeter 파라미터가 설정되지 않은 경우 함수는 `"Missing the required greeter parameter."`라는 오류 메시지를 반환합니다. 이 함수의 이름을 `HelloWorld`로 지정합니다.

Lambda 콘솔에서 또는 AWS CLI를 사용하여 이를 생성할 수 있습니다. 이 단원에서는 다음 ARN을 사용하여 이 함수를 참조합니다.

```
arn:aws:lambda:us-east-1:123456789012:function:HelloWorld
```

백엔드에 설정된 Lambda 함수를 사용하여 API를 설정하는 단계로 이동합니다.<a name="set-up-lambda-custom-integration-using-cli"></a>

**AWS CLI를 사용하여 Lambda 사용자 지정 통합 설정**

1. 다음 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 명령을 사용하면 API를 생성할 수 있습니다.

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   출력은 다음과 같습니다.

   ```
   {
       "name": "HelloWorld (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   이 예제에서는 API `id`(`te6si5ach7`)와 `rootResourceId`(`krznpq9xpg`)를 사용합니다.

1. 다음 [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 명령을 사용하면 `/greeting`의 API Gateway [리소스](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)를 생성할 수 있습니다.

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part greeting
   ```

   출력은 다음과 같습니다.

   ```
   {
       "path": "/greeting", 
       "pathPart": "greeting", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   다음 단계에서는 `greeting` 리소스의 `id` 값(`2jf6xt`)을 사용하여 `/greeting` 리소스에 대한 메서드를 생성합니다.

1. 다음 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 명령을 사용하면 `GET /greeting?greeter={name}`의 API 메서드 요청을 생성할 수 있습니다.

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method GET \
          --authorization-type "NONE" \
          --request-parameters method.request.querystring.greeter=false
   ```

   출력은 다음과 같습니다.

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE", 
       "requestParameters": {
           "method.request.querystring.greeter": false
       }
   }
   ```

   이 API 메서드를 통해 클라이언트는 백엔드에서 Lambda 함수의 인사를 수신할 수 있습니다. `greeter` 파라미터는 선택 사항인데, 그 이유는 백엔드가 익명 호출자 또는 자기 동일 호출자를 처리해야 하기 때문입니다.

1. 다음 [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 명령을 사용하면 `GET /greeting?greeter={name}`의 메서드 요청에 대한 `200 OK` 응답을 설정할 수 있습니다.

   ```
   aws apigateway put-method-response \
           --rest-api-id te6si5ach7 \ 
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200
   ```

   

1. 다음 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 명령을 사용하면 `HelloWorld`라는 Lambda 함수와 `GET /greeting?greeter={name}` 메서드의 통합을 설정할 수 있습니다. 이 함수는 `"Hello, {name}!"` 파라미터가 제공되면 `greeter`이라는 메시지로, 쿼리 문자열 파라미터가 설정되어 있지 않으면 `"Hello, World!"`라는 메시지로 요청에 응답합니다.

   ```
   aws apigateway put-integration \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --type AWS \
           --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
   ```

   여기에 제공된 매핑 템플릿은 `greeter` 쿼리 문자열 파라미터를 JSON 페이로드의 `greeter` 속성으로 변환합니다. 이것이 필요한 이유는 Lambda 함수에 대한 입력은 본문에 표시되어야 하기 때문입니다.
**중요**  
Lambda 통합의 경우에는 [함수 호출을 위한 Lambda 서비스 작업의 사양](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)에 따라 통합 요청에 대해 `POST`의 HTTP 메서드를 사용해야 합니다. `uri` 파라미터는 함수 호출 작업의 ARN입니다.  
출력은 다음과 같습니다.

   ```
   {
       "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"
   }
   ```

   `apigAwsProxyRole`의 IAM 역할에는 `apigateway` 서비스가 Lambda 함수를 호출하도록 허용하는 정책이 있어야 합니다. `credentials`에 IAM 역할을 제공하는 대신 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 명령을 호출하여 리소스 기반 권한을 추가할 수 있습니다. API Gateway 콘솔은 이 방식으로 권한을 추가합니다.

1. 다음 [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) 명령을 사용하면 Lambda 함수 출력을 `200 OK` 메서드 응답으로 클라이언트에 전달하도록 통합 응답을 설정할 수 있습니다.

   ```
    aws apigateway put-integration-response \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200 \
           --selection-pattern ""
   ```

   빈 문자열에 선택 패턴을 설정하면 `200 OK` 응답이 기본값입니다.

   출력은 다음과 같습니다.

   ```
    {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

1. 다음 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 명령을 사용하면 API를 `test` 스테이지에 배포할 수 있습니다.

   ```
   aws apigateway create-deployment \
           --rest-api-id te6si5ach7 \
           --stage-name test
   ```

1.  터미널에서 다음 cURL 명령을 사용하여 API를 테스트합니다.

   ```
   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'
   ```

# 백엔드 Lambda 함수의 비동기 호출 설정
<a name="set-up-lambda-integration-async"></a>

Lambda 비프록시(사용자 지정)에서, 백엔드 Lambda 함수는 기본적으로 동기적으로 호출됩니다. 이 동작은 대부분의 REST API 작업에 적합합니다. 그러나 일부 애플리케이션은 일반적으로 별도의 백엔드 구성 요소에 의해 (배치 작업 또는 장기 지연 작업으로) 비동기적으로 작업을 수행해야 합니다. 이 경우 백엔드 Lambda 함수는 비동기적으로 호출되며 프런트엔드 REST API 메서드가 결과를 반환하지 않습니다.

[Lambda 호출 유형](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html)을 `'Event'`로 지정하여 Lambda 함수를 Lambda 비프록시 통합이 비동기적으로 호출되도록 구성할 수 있습니다. 구성 방법은 다음과 같습니다.

## API Gateway 콘솔에서 Lambda 비동기 호출 구성
<a name="asynchronous-invocation-console-examples"></a>

모든 호출이 비동기식 인 경우:
+ **통합 요청**에서 정적 값이 `'Event'`인 `X-Amz-Invocation-Type` 헤더를 추가합니다.

호출이 비동기식인지 동기식인지 여부를 클라이언트가 결정하려면 다음을 수행하세요.

1. **메서드 요청**에서 `InvocationType` 헤더를 추가합니다.

1. **통합 요청**에서 매핑 표현식이 `method.request.header.InvocationType`인 `X-Amz-Invocation-Type` 헤더를 추가합니다.

1. 클라이언트는 API 요청에 비동기식 호출의 경우 `InvocationType: Event` 헤더를, 동기식 호출의 경우 `InvocationType: RequestResponse` 헤더를 포함할 수 있습니다.

## OpenAway를 사용하여 Lambda 비동기 호출 구성
<a name="asynchronous-invocation-OpenAPI-examples"></a>

모든 호출이 비동기식 인 경우:
+  **x-amazon-apigateway-integration** 섹션에 `X-Amz-Invocation-Type` 헤더를 추가합니다.

  ```
  "x-amazon-apigateway-integration" : {
            "type" : "aws",
            "httpMethod" : "POST",
            "uri" : "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:my-function/invocations",
            "responses" : {
              "default" : {
                "statusCode" : "200"
              }
            },
            "requestParameters" : {
              "integration.request.header.X-Amz-Invocation-Type" : "'Event'"
            },
            "passthroughBehavior" : "when_no_match",
            "contentHandling" : "CONVERT_TO_TEXT"
          }
  ```

호출이 비동기식인지 동기식인지 여부를 클라이언트가 결정하려면 다음을 수행하세요.

1.  모든 [OpenAPI Path Item Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#pathItemObject)(OpenAPI 경로 항목 객체)에 다음 헤더를 추가합니다.

   ```
   "parameters" : [ {
   "name" : "InvocationType",
   "in" : "header",
   "schema" : {
     "type" : "string"
   }
   } ]
   ```

1.  **x-amazon-apigateway-integration** 섹션에 `X-Amz-Invocation-Type` 헤더를 추가합니다.

   ```
   "x-amazon-apigateway-integration" : {
             "type" : "aws",
             "httpMethod" : "POST",
             "uri" : "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:my-function/invocations",
             "responses" : {
               "default" : {
                 "statusCode" : "200"
               }
             },
             "requestParameters" : {
               "integration.request.header.X-Amz-Invocation-Type" : "method.request.header.InvocationType"
             },
             "passthroughBehavior" : "when_no_match",
             "contentHandling" : "CONVERT_TO_TEXT"
           }
   ```

1.  클라이언트는 API 요청에 비동기식 호출의 경우 `InvocationType: Event` 헤더를, 동기식 호출의 경우 `InvocationType: RequestResponse` 헤더를 포함할 수 있습니다.

## CloudFormation을 사용하여 Lambda 비동기 간접 호출을 구성합니다.
<a name="asynchronous-invocation-cfn-examples"></a>

다음 CloudFormation 템플릿은 비동기 호출을 위해 `AWS::ApiGateway::Method`를 구성하는 방법을 보여줍니다.

모든 호출이 비동기식 인 경우:

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: "'Event'"
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

호출이 비동기식인지 동기식인지 여부를 클라이언트가 결정하려면 다음을 수행하세요.

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      RequestParameters:
        method.request.header.InvocationType: false
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: method.request.header.InvocationType
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

 클라이언트는 API 요청에 비동기식 호출의 경우 `InvocationType: Event` 헤더를, 동기식 호출의 경우 `InvocationType: RequestResponse` 헤더를 포함할 수 있습니다.

# API Gateway에서 Lambda 오류 처리
<a name="handle-errors-in-lambda-integration"></a>

 Lambda 사용자 지정 통합의 경우에는 Lambda가 통합 응답에서 반환한 오류를 클라이언트에 대한 표준 HTTP 오류 응답으로 매핑해야 합니다. 그렇게 하지 않으면 Lambda 오류는 기본적으로 API 사용자가 직관적으로 이해하기 어려운 `200 OK` 응답으로 반환됩니다.

 Lambda가 반환할 수 있는 오류 유형은 표준 오류와 사용자 지정 오류, 두 가지입니다. API에서 이 두 가지 오류를 다르게 처리해야 합니다.

 Lambda 프록시 통합의 경우, Lambda는 다음 형식의 출력을 반환해야 합니다.

```
{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}
```

이 출력에서 `statusCode`는 일반적으로 클라이언트 오류의 경우 `4XX`, 서버 오류의 경우 `5XX`입니다. API Gateway는 지정된 `statusCode`에 따라 Lambda 오류를 HTTP 오류 응답에 매핑함으로써 이러한 오류를 처리합니다. API Gateway에서 클라이언트에 대한 응답의 일부로 오류 유형(예: `InvalidParameterException`)을 전달하려면 Lambda 함수가 `"X-Amzn-ErrorType":"InvalidParameterException"` 속성에 헤더(예: `headers`)를 포함해야 합니다.

**Topics**
+ [API Gateway에서 표준 Lambda 오류 처리](#handle-standard-errors-in-lambda-integration)
+ [API Gateway에서 사용자 지정 Lambda 오류 처리](#handle-custom-errors-in-lambda-integration)

## API Gateway에서 표준 Lambda 오류 처리
<a name="handle-standard-errors-in-lambda-integration"></a>

표준 AWS Lambda의 오류 형식은 다음과 같습니다.

```
{
  "errorMessage": "<replaceable>string</replaceable>",
  "errorType": "<replaceable>string</replaceable>",
  "stackTrace": [
    "<replaceable>string</replaceable>",
    ...
  ]
}
```

 여기서 `errorMessage`는 오류의 문자열 표현식입니다. `errorType`은 언어 종속적 오류 또는 예외 유형입니다. `stackTrace`는 문자열 표현식 목록으로, 오류를 유발하는 스택 추적을 보여 줍니다.

 예를 들어 다음과 같은 JavaScript(Node.js) Lambda 함수를 생각해 보세요.

```
export const handler = function(event, context, callback) {
    callback(new Error("Malformed input ..."));
};
```

이 함수는 오류 메시지 `Malformed input ...`이 포함된 다음과 같은 표준 Lambda 오류를 반환합니다.

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "export const handler (/var/task/index.js:3:14)"
  ]
}
```

 마찬가지로 다음과 같은 Python Lambda 함수를 생각해 보세요. 동일한 `Exception` 오류 메시지와 함께 `Malformed input ...`을 야기하는 함수입니다.

```
def lambda_handler(event, context):
    raise Exception('Malformed input ...')
```

 이 함수는 다음과 같은 표준 Lambda 오류를 반환합니다.

```
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      3,
      "lambda_handler",
      "raise Exception('Malformed input ...')"
    ]
  ],
  "errorType": "Exception",
  "errorMessage": "Malformed input ..."
}
```

 `errorType` 및 `stackTrace` 속성 값은 언어 종속적입니다. 또한 이 표준 오류는 `Error` 객체의 확장이거나 `Exception` 클래스의 하위 클래스인 모든 오류 객체에 적용됩니다.

 표준 Lambda 오류를 메서드 응답에 매핑하려면, 먼저 주어진 Lambda 오류의 HTTP 상태 코드를 결정해야 합니다. 그런 다음 주어진 HTTP 상태 코드와 연결된 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html)의 `[selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` 속성에서 정규 표현식 패턴을 설정합니다. API Gateway 콘솔에서 이 `selectionPattern`은 각 통합 응답 아래의 **통합 응답** 섹션에 **Lambda 오류 Regex**로 표시됩니다.

**참고**  
API Gateway는 응답 매핑을 위해서 Java 패턴 스타일 정규식을 사용합니다. 자세한 내용은 Oracle 설명서의 [패턴 ](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) 단원을 참조하세요

 예를 들어, 다음 [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html)를 사용하여 새 `selectionPattern` 표현식을 설정합니다.

```
aws apigateway put-integration-response --rest-api-id z0vprf0mdh --resource-id x3o5ih --http-method GET --status-code 400 --selection-pattern "Malformed.*" --region us-west-2
```

 [메서드 응답](api-gateway-method-settings-method-response.md#setup-method-response-status-code)에 해당하는 오류 코드(`400`)도 설정해야 합니다. 그렇지 않으면 API Gateway는 실행 시간에 잘못된 구성 오류 응답을 내보냅니다.

**참고**  
 실행 시간에 API Gateway는 Lambda 오류의 `errorMessage`를 메시지를 `selectionPattern` 속성의 정규식 패턴과 비교합니다. 양쪽이 일치하면 API Gateway는 Lambda 오류를 해당 HTTP 상태 코드의 HTTP 응답으로 반환합니다. 일치하지 않으면 API Gateway는 오류를 기본 응답으로 반환하고, 만일 기본 응답이 구성되어 있지 않으면 잘못된 구성 예외로 내보냅니다.  
 지정된 응답에 대해 `selectionPattern` 값을 `.*`로 설정하면 이 응답이 기본 응답으로 다시 설정됩니다. 이는 해당 선택 패턴이 null(즉. 지정되지 않은 오류 메시지)을 포함하는 모든 오류 메시지와 일치하기 때문입니다. 그 결과로 나타나는 매핑은 기본 매핑을 무시합니다. `.+`를 선택 패턴으로 사용하여 응답을 필터링하는 경우 응답이 일치하지 않을 수 있음을 인지하는 것이 좋습니다. 줄바꿈('`\n`) 문자를 포함하는 응답과 일치하지 않을 수 있습니다.

 `selectionPattern`를 사용하여 기존의 AWS CLI 값을 업데이트하려면 [integrationresponse:update](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) 작업을 호출하여 `/selectionPattern` 경로 값을 `Malformed*` 패턴의 지정된 regex 표현식으로 바꿉니다.



API Gateway 콘솔을 사용하여 `selectionPattern` 표현식을 설정하려면, 지정된 HTTP 상태 코드의 통합 응답을 설정하거나 업데이트할 때 **Lambda 오류 Regex** 텍스트 상자에 원하는 표현식을 입력합니다.

## API Gateway에서 사용자 지정 Lambda 오류 처리
<a name="handle-custom-errors-in-lambda-integration"></a>

 AWS Lambda에서는 사용자 지정 오류 객체를 앞 단원에서 다룬 표준 오류 대신 JSON 문자열로 반환할 수 있습니다. 유효한 모든 JSON 객체를 오류로 사용할 수 있습니다. 예를 들어 다음 JavaScript(Node.js) Lambda 함수는 사용자 지정 오류를 반환합니다.

```
export const handler = (event, context, callback) => {
    ...
    // Error caught here:
    var myErrorObj = {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
    callback(JSON.stringify(myErrorObj));
};
```

 `myErrorObj`을 호출하여 함수를 종료하려면 먼저 `callback` 객체를 JSON 문자열로 변환해야 합니다. 그렇지 않으면 `myErrorObj`가 `"[object Object]"`의 문자열로 반환됩니다. API 메서드가 앞의 Lambda 함수와 통합되면 API Gateway는 다음과 같은 페이로드의 통합 응답을 받습니다.

```
{
    "errorMessage": "{\"errorType\":\"InternalServerError\",\"httpStatus\":500,\"requestId\":\"e5849002-39a0-11e7-a419-5bb5807c9fb2\",\"trace\":{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}}"
}
```

 통합 응답과 마찬가지로 이 오류 응답을 그대로 메서드 응답으로 전달할 수 있습니다. 아니면 매핑 템플릿을 사용하여 페이로드를 다른 형식으로 변환할 수도 있습니다. 예를 들어, `500` 상태 코드의 메서드 응답이라면 다음과 같은 본문 매핑 템플릿을 고려해 보세요.

```
{
    errorMessage: $input.path('$.errorMessage');
}
```

이 템플릿은 사용자 지정 오류 JSON 문자열이 포함된 통합 응답 본문을 다음과 같은 메서드 응답 본문으로 변환합니다. 이 메서드 응답 본문에는 사용자 지정 오류 JSON 객체가 들어 있습니다.

```
{
    "errorMessage" : {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
};
```

 API 요구 사항에 따라 사용자 지정 오류 속성 중 일부 또는 전부를 메서드 응답 헤더 파라미터로 전달해야 할 수 있습니다. 그러려면 통합 응답 본문의 사용자 지정 오류 매핑을 메서드 응답 헤더에 적용하면 됩니다.

예를 들어, 다음 OpenAPI 확장은 각각 `errorMessage.errorType`, `errorMessage.httpStatus`, `errorMessage.trace.function` 및 `errorMessage.trace` 속성에서 `error_type`, `error_status`, `error_trace_function` 및 `error_trace` 헤더로 매핑을 정의합니다.

```
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
          "statusCode": "200",
          "responseParameters": {
            "method.response.header.error_trace_function": "integration.response.body.errorMessage.trace.function",
            "method.response.header.error_status": "integration.response.body.errorMessage.httpStatus",
            "method.response.header.error_type": "integration.response.body.errorMessage.errorType",
            "method.response.header.error_trace": "integration.response.body.errorMessage.trace"
          },
          ...
        }
    }
}
```

 API Gateway는 실행 시간에 헤더 매핑을 수행할 때 `integration.response.body` 파라미터를 역직렬화합니다. 그러나 이런 역직렬화는 Lambda 사용자 지정 오류 응답의 본문-헤더 매핑에만 적용되며, `$input.body`를 사용하는 본문-본문 매핑에는 적용되지 않습니다. 이러한 사용자 지정 오류의 본문-헤더 매핑을 사용할 경우, 클라이언트가 받는 메서드 응답에 다음 헤더가 포함되어 있습니다. 단, 메서드 요청에 `error_status`, `error_trace`, `error_trace_function`, `error_type` 헤더가 선언되어 있어야 합니다.

```
"error_status":"500",
"error_trace":"{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}",
"error_trace_function":"abc()",
"error_type":"InternalServerError"
```

통합 응답 본문의 `errorMessage.trace` 속성은 복잡한 속성입니다. `error_trace` 헤더에 JSON 문자열로 매핑됩니다.