

# CloudFront Functions를 사용하여 엣지에서 사용자 지정
<a name="cloudfront-functions"></a>

CloudFront 함수를 사용하면 지연 시간에 민감한 대규모 CDN 사용자 지정을 위해 JavaScript로 경량 함수를 작성할 수 있습니다. 함수는 CloudFront를 통해 흐르는 요청 및 응답을 조작하고, 기본 인증 및 권한 부여를 수행하고, 엣지에서 HTTP 응답을 생성하는 등의 작업을 수행할 수 있습니다. CloudFront 함수 런타임 환경은 밀리초 미만의 시작 시간을 제공하고 초당 수백만 건의 요청을 처리할 수 있도록 즉시 확장되며 매우 안전합니다. CloudFront 함수는 CloudFront의 기본 기능입니다. 즉, CloudFront 내에서 완전히 코드를 빌드, 테스트 및 배포할 수 있습니다.

CloudFront 배포를 CloudFront 함수와 연결하면 CloudFront가 CloudFront 엣지 로케이션에서 요청 및 응답을 가로채고 함수에 전달합니다. 다음 이벤트가 발생할 때 CloudFront 함수를 간접 호출할 수 있습니다.
+ CloudFront가 최종 사용자의 요청을 수신할 때(최종 사용자 요청)
+ CloudFront가 최종 사용자에게 응답을 반환하기 전(최종 사용자 응답)
+ TLS 연결 설정(연결 요청) 중 - 현재 상호 TLS(mTLS) 연결에 사용 가능

CloudFront Functions에 대한 자세한 내용은 다음 주제를 참조하세요.

**Topics**
+ [

# 튜토리얼: CloudFront Functions를 사용하여 간단한 함수 생성
](functions-tutorial.md)
+ [

# 튜토리얼: 키 값을 포함하는 CloudFront 함수 생성
](functions-tutorial-kvs.md)
+ [

# 함수 코드 작성
](writing-function-code.md)
+ [

# 함수 생성
](create-function.md)
+ [

# 함수 테스트
](test-function.md)
+ [

# 함수 업데이트
](update-function.md)
+ [

# 함수 게시
](publish-function.md)
+ [

# 배포에 함수 연결
](associate-function.md)
+ [

# Amazon CloudFront KeyValueStore
](kvs-with-functions.md)

# 튜토리얼: CloudFront Functions를 사용하여 간단한 함수 생성
<a name="functions-tutorial"></a>

이 자습서에서는 CloudFront 함수를 시작하는 방법을 설명합니다. 뷰어를 다른 URL로 리디렉션하고 사용자 지정 응답 헤더를 반환하는 간단한 함수를 만들 수 있습니다.

**Contents**
+ [

## 사전 조건
](#functions-tutorial-prerequisites)
+ [

## 함수 생성
](#functions-tutorial-create)
+ [

## 함수 확인
](#functions-tutorial-verify)

## 사전 조건
<a name="functions-tutorial-prerequisites"></a>

CloudFront 함수를 사용하려면 CloudFront 배포가 필요합니다. 계정이 없는 경우 [CloudFront 표준 배포 시작](GettingStarted.SimpleDistribution.md) 단원을 참조하십시오.

## 함수 생성
<a name="functions-tutorial-create"></a>

CloudFront 콘솔을 사용하여 뷰어를 다른 URL로 리디렉션하고 사용자 지정 응답 헤더를 반환하는 간단한 함수를 만들 수 있습니다.

**CloudFront 함수를 생성하려면**

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택한 후, **함수 생성**을 선택합니다.

1. **함수 생성** 페이지에서 **이름**에 *MyFunctionName*과 같은 함수 이름을 입력합니다.

1. (선택 사항) 설명에 **Simple test function**과 같은 기능에 대한 **설명**을 입력합니다.

1. **런타임**의 경우 선택한 기본 JavaScript 버전을 유지합니다.

1. **함수 생성**을 선택합니다.

1. 다음 함수 코드를 복사합니다. 이 함수 코드는 최종 사용자를 다른 URL로 리디렉션하고 사용자 지정 응답 헤더도 반환합니다.

   ```
   function handler(event) {
       // NOTE: This example function is for a viewer request event trigger. 
       // Choose viewer request for event trigger when you associate this function with a distribution. 
       var response = {
           statusCode: 302,
           statusDescription: 'Found',
           headers: {
               'cloudfront-functions': { value: 'generated-by-CloudFront-Functions' },
               'location': { value: 'https://aws.amazon.com/cloudfront/' }
           }
       };
       return response;
   }
   ```

1. **함수 코드**의 경우 코드를 코드 편집기에 붙여넣어 기본 코드를 대체합니다.

1. **변경 사항 저장**을 선택합니다.

1. (선택 사항) 함수를 게시하기 전에 테스트할 수 있습니다. 이 자습서에서는 함수를 테스트하는 방법에 대해 설명하지 않습니다. 자세한 내용은 [함수 테스트](test-function.md) 섹션을 참조하세요.

1. **게시** 탭을 선택한 다음 **게시 함수**를 선택합니다. 함수를 CloudFront 배포와 연결하려면 먼저 함수를 게시해야 합니다**.

1. 다음으로 함수를 배포 또는 캐시 동작과 연결할 수 있습니다. *MyFunctionName*페이지에서 **게시** 탭을 선택합니다.
**주의**  
다음 단계에서는 테스트에 사용할 배포 또는 캐시 동작을 선택합니다. 이 테스트 함수를 프로덕션 환경에서 사용되는 배포 또는 캐시 동작과 연결하지 마세요.

1. **Add association**을 선택합니다.

1. **연결** 대화 상자에서 배포 및/또는 캐시 동작을 선택합니다. **이벤트 유형**의 경우 기본값을 유지합니다.

1. **연결 추가**를 선택합니다.

   **연결된 배포** 테이블에 연결된 배포가 표시됩니다.

1. 연결된 배포가 배포될 때까지 몇 분 정도 기다립니다. 그런 다음 배포 상태를 확인하려면 **연결된 배포** 테이블에서 해당 배포를 선택하고 **배포 보기**를 선택합니다.

   배포의 상태가 **배포됨**(Deployed)이면 함수가 작동하는지 확인할 준비가 된 것입니다.

## 함수 확인
<a name="functions-tutorial-verify"></a>

함수를 배포한 후 해당 함수가 배포에서 작동하는지 확인할 수 있습니다.

**함수를 확인하려면**

1. 웹 브라우저에서 배포의 도메인 이름(예: `https://d111111abcdef8.cloudfront.net`)으로 이동합니다.

   이 함수는 브라우저로 리디렉션을 반환하므로 브라우저가 자동으로 `https://aws.amazon.com/cloudfront/`(으)로 이동합니다.

1. 명령줄 창에서 같은 **curl** 도구를 사용하여 배포의 도메인 이름으로 요청을 보낼 수 있습니다.

   ```
   curl -v https://d111111abcdef8.cloudfront.net/
   ```

   응답에는 리디렉션 응답(`302 Found`)과 함수가 추가한 사용자 지정 응답 헤더가 표시됩니다. 응답은 다음 예와 같이 보일 수 있습니다.  
**Example**  

   ```
   curl -v https://d111111abcdef8.cloudfront.net/
   > GET / HTTP/1.1
   > Host: d111111abcdef8.cloudfront.net
   > User-Agent: curl/7.64.1
   > Accept: */*
   >
   < HTTP/1.1 302 Found
   < Server: CloudFront
   < Date: Tue, 16 Mar 2021 18:50:48 GMT
   < Content-Length: 0
   < Connection: keep-alive
   < Location: https://aws.amazon.com/cloudfront/
   < Cloudfront-Functions: generated-by-CloudFront-Functions
   < X-Cache: FunctionGeneratedResponse from cloudfront
   < Via: 1.1 3035b31bddaf14eded329f8d22cf188c.cloudfront.net (CloudFront)
   < X-Amz-Cf-Pop: PHX50-C2
   < X-Amz-Cf-Id: ULZdIz6j43uGBlXyob_JctF9x7CCbwpNniiMlmNbmwzH1YWP9FsEHg==
   ```

# 튜토리얼: 키 값을 포함하는 CloudFront 함수 생성
<a name="functions-tutorial-kvs"></a>

이 자습서에서는 CloudFront 함수를 사용하여 키 값을 포함하는 방법을 보여줍니다. 키 값은 키 값 페어의 일부입니다. 사용자는 키 값 페어의 이름을 함수 코드에 포함할 수 있습니다. 함수 실행 시 CloudFront가 이름을 값으로 대체합니다.

키 값 페어는 키 값 저장소에 저장되는 변수입니다. 함수에 하드 코딩된 값 대신 키를 사용하면 함수가 더 유연해집니다. 코드 변경 내용을 배포하지 않고도 키 값을 변경할 수 있습니다. 키 값 페어를 사용하면 함수 크기를 줄일 수도 있습니다. 자세한 내용은 [Amazon CloudFront KeyValueStore](kvs-with-functions.md) 섹션을 참조하세요.

**Contents**
+ [

## 사전 조건
](#functions-kvs-tutorial-prerequisites)
+ [

## 키 값 저장소 생성
](#functions-kvs-tutorial-kvs-step)
+ [

## 키 값 저장소에 키 값 페어 추가
](#add-key-value-pairs-to-store)
+ [

## 키 값 저장소를 함수와 연결
](#functions-kvs-tutorial-functions-step)
+ [

## 함수 코드 테스트 및 게시
](#test-and-publish-function-code)

## 사전 조건
<a name="functions-kvs-tutorial-prerequisites"></a>

CloudFront Functions 함수 및 키 값 저장소를 처음 사용하는 경우 [튜토리얼: CloudFront Functions를 사용하여 간단한 함수 생성](functions-tutorial.md)의 튜토리얼을 따르는 것이 좋습니다.

해당 튜토리얼을 완료한 후에는 이 튜토리얼을 따라 이전에 생성한 함수를 확장할 수 있습니다. 이 튜토리얼에서는 키 값 저장소를 먼저 생성하려는 것이 좋습니다.

## 키 값 저장소 생성
<a name="functions-kvs-tutorial-kvs-step"></a>

먼저 함수에 사용할 키 값 저장소를 생성합니다.

**키 값 저장소를 생성하려면**

1. 함수에 포함하려는 키 값 페어를 계획합니다. 키 이름을 적어두세요. 함수에 사용하려는 키 값 페어는 하나의 키 값 저장소에 있어야 합니다.

1. 작업 순서를 결정합니다. 다음 두 가지 방법으로 진행할 수 있습니다.
   + 키 값 저장소를 생성하고 저장소에 키 값 페어를 추가합니다. 그런 다음 함수를 생성(또는 수정)하고 키 이름을 통합합니다.
   + 또는 함수를 생성(또는 수정)하고 사용하려는 키 이름으로 통합합니다. 그런 다음 키 값 저장소를 생성하고 저장소에 키 값 페어를 추가합니다.

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택한 다음 **KeyValueStores** 탭을 선택합니다.

1. **KeyValueStore 생성**을 선택하고 다음과 같이 필드를 작성합니다.
   + 저장소 이름을 입력하고 필요한 경우 설명을 입력합니다.
   + **S3 URI**를 비워 둡니다. 이 튜토리얼에서는 키 값 페어를 수동으로 입력합니다.

1. **생성(Create)**을 선택합니다. 새로운 키 값 저장소의 세부 정보 페이지가 나타납니다. 이 페이지에는 현재 비어 있는 **키 값 페어** 섹션이 포함되어 있습니다.

## 키 값 저장소에 키 값 페어 추가
<a name="add-key-value-pairs-to-store"></a>

그런 다음 이전에 생성한 키 값 저장소에 키 값 페어의 목록을 수동으로 추가합니다.

**키 값 저장소에 키 값 페어를 추가하려면**

1. **키 값 페어** 섹션에서 **키 값 페어 추가**를 선택합니다.

1. **태그 추가**를 선택한 다음 키와 값을 입력합니다. 확인 표시를 선택하여 변경 사항을 확인하고 이 단계를 반복하여 더 추가합니다.

1. 작업을 마쳤으면 **변경 사항 저장**을 선택하여 키 값 페어를 키 값 저장소에 저장합니다. 확인 대화 상자에서 **완료**를 선택합니다.

이제 키 값 페어 그룹이 포함된 키 값 저장소가 생겼습니다.



## 키 값 저장소를 함수와 연결
<a name="functions-kvs-tutorial-functions-step"></a>

이제 키 값 저장소가 생성되었습니다. 그리고 키 값 저장소의 키 이름을 포함하는 함수를 만들거나 수정했습니다. 이제 키 값 저장소와 함수를 연결할 수 있습니다. 이 연결은 함수 내에서 생성할 수 있습니다.

**키 값 저장소를 함수와 연결하려면**

1. 탐색 창에서 **함수**를 선택합니다. 기본적으로 **함수** 탭이 맨 위에 표시됩니다.

1. 함수 이름을 선택하고 **연결된 KeyValueStore** 섹션에서 **기존 KeyValueStore 연결**을 선택합니다.

1. 키 값 저장소를 선택하고 **KeyValueStore 연결**을 선택합니다.

**참고**  
각 함수에는 하나의 키 값 저장소만 연결할 수 있습니다.

## 함수 코드 테스트 및 게시
<a name="test-and-publish-function-code"></a>

키 값 저장소를 함수와 연결한 후 함수 코드를 테스트하고 게시할 수 있습니다. 다음을 수행할 때를 포함하여 함수 코드를 수정할 때마다 항상 함수 코드를 테스트해야 합니다.
+ 키 값 저장소를 함수와 연결할 때
+ 새로운 키 값 페어를 포함하도록 함수와 해당 키 값 저장소를 수정할 때
+ 키 값 페어의 값을 변경할 때

**함수 코드를 테스트하고 게시하려면**

1. 함수를 테스트하는 방법은 [함수 테스트](test-function.md) 섹션을 참조하세요. `DEVELOPMENT` 스테이지에서 함수를 테스트하도록 선택해야 합니다.

1. `LIVE` 환경에서 새 키 값 페어 또는 수정된 키 값 페어와 함께 함수를 사용할 준비가 되면 함수를 게시합니다.

   함수를 게시하면 CloudFront는 `DEVELOPMENT` 스테이지에서 라이브 스테이지로 함수 버전을 복사합니다. 함수에는 새 코드가 포함되며 키 값 저장소와 연결됩니다. 라이브 스테이지에서는 연결을 다시 수행하지 않아도 됩니다.

   함수를 게시하는 방법은 [함수 게시](publish-function.md) 섹션을 참조하세요.

# 함수 코드 작성
<a name="writing-function-code"></a>

CloudFront Functions를 사용하여 지연 시간에 민감한 대규모 CDN 사용자 지정을 위해 JavaScript로 경량 함수를 작성할 수 있습니다. 함수 코드는 CloudFront를 통해 흐르는 요청 및 응답을 조작하고, 기본 인증 및 권한 부여를 수행하고, 엣지에서 HTTP 응답을 생성하는 등의 작업을 수행할 수 있습니다.

CloudFront Functions의 함수 코드를 작성하는 데 도움을 받으려면 다음 주제를 참조하세요. 코드 예제는 [CloudFront의 CloudFront Functions 예제](service_code_examples_cloudfront_functions_examples.md) 및 GitHub의 [amazon-cloudfront-functions 리포지토리](https://github.com/aws-samples/amazon-cloudfront-functions)를 참조하시기 바랍니다.

**Topics**
+ [

# 함수 용도 결정
](function-code-choose-purpose.md)
+ [이벤트 구조](functions-event-structure.md)
+ [JavaScript 런타임 기능](functions-javascript-runtime-features.md)
+ [

# 키 값 저장소를 위한 도우미 메서드
](functions-custom-methods.md)
+ [

# 오리진 수정용 헬퍼 메서드
](helper-functions-origin-modification.md)
+ [

# CloudFront SaaS Manager 속성에 대한 헬퍼 메서드
](saas-specific-logic-function-code.md)
+ [

# async 및 await 사용
](async-await-syntax.md)
+ [

# CloudFront Functions에 대한 CWT 지원
](cwt-support-cloudfront-functions.md)
+ [

# 일반 헬퍼 메서드
](general-helper-methods.md)

# 함수 용도 결정
<a name="function-code-choose-purpose"></a>

함수 코드를 작성하기 전에 함수의 용도를 결정합니다. CloudFront 함수의 대부분의 함수는 다음 용도 중 하나를 가지고 있습니다.

**Topics**
+ [

## 뷰어 요청 이벤트 유형의 HTTP 요청 수정
](#function-code-modify-request)
+ [

## 뷰어 요청 이벤트 유형에 HTTP 응답 생성
](#function-code-generate-response)
+ [

## 뷰어 응답 이벤트 유형의 HTTP 응답 수정
](#function-code-modify-response)
+ [

## 연결 요청 이벤트 유형에서 mTLS 연결 검증
](#function-code-connection-request)
+ [

## 관련 정보
](#related-information-cloudfront-functions-purpose)

함수의 용도에 관계없이 `handler`은(는) 모든 함수의 진입점입니다. CloudFront에 의해 함수에 전달되는 `event`(이)라고 하는 단일 인수가 필요합니다. `event`은(는) HTTP 요청(그리고 함수가 HTTP 응답을 수정하는 경우 응답)의 표현을 포함하는 JSON 객체입니다.

## 뷰어 요청 이벤트 유형의 HTTP 요청 수정
<a name="function-code-modify-request"></a>

함수는 CloudFront가 최종 사용자(클라이언트)로부터 수신하는 HTTP 요청을 수정하고 수정된 요청을 CloudFront로 반환하여 처리를 계속할 수 있습니다. 예를 들어 함수 코드가 [캐시 키](understanding-the-cache-key.md)를 정규화하거나 요청 헤더를 수정할 수 있습니다.

HTTP 요청을 수정하는 함수를 만들고 게시한 후 *뷰어 요청* 이벤트 유형 연결을 추가해야 합니다. 자세한 내용은 [함수 생성](functions-tutorial.md#functions-tutorial-create) 섹션을 참조하세요. 즉, 요청된 객체가 CloudFront 캐시에 있는지 여부를 확인하기 위해 점검하기 전에 CloudFront가 뷰어의 요청을 수신할 때마다 함수가 실행됩니다.

**Example 예제**  
다음 유사 코드는 HTTP 요청을 수정하는 함수의 구조를 보여줍니다.  

```
function handler(event) {
    var request = event.request;

    // Modify the request object here.

    return request;
}
```
이 함수는 수정된 `request` 객체를 CloudFront로 반환합니다. CloudFront는 CloudFront 캐시에서 캐시 적중률을 확인하고 필요한 경우 오리진에 요청을 전송하여 반환된 요청을 계속 처리합니다.

## 뷰어 요청 이벤트 유형에 HTTP 응답 생성
<a name="function-code-generate-response"></a>

함수는 CloudFront에서 캐시된 응답이나 추가 처리를 확인하지 않고 엣지에서 HTTP 응답을 생성하여 최종 사용자(클라이언트)에게 직접 반환할 수 있습니다. 예를 들어 함수 코드는 요청을 새 URL로 리디렉션하거나 권한 부여를 확인하고 권한 없는 요청에 `401` 또는 `403` 응답을 반환할 수 있습니다.

HTTP 응답을 생성하는 함수를 생성할 때는 *최종 사용자 요청* 이벤트 유형을 선택해야 합니다. 즉, CloudFront가 추가 요청을 처리하기 전에 CloudFront가 최종 사용자의 요청을 수신할 때마다 함수가 실행됩니다.

**Example 예제**  
다음 유사 코드는 HTTP 응답을 생성하는 함수의 구조를 보여줍니다.  

```
function handler(event) {
    var request = event.request;

    var response = ...; // Create the response object here,
                        // using the request properties if needed.

    return response;
}
```
이 함수는 CloudFront에 `response` 객체를 반환하며, CloudFront는 CloudFront 캐시를 확인하거나 오리진에 요청을 보내지 않고 즉시 최종 사용자에게 반환합니다.

## 뷰어 응답 이벤트 유형의 HTTP 응답 수정
<a name="function-code-modify-response"></a>

CloudFront가 HTTP 응답을 최종 사용자(클라이언트)에게 전송하기 전에 함수는 HTTP 응답을 수정할 수 있습니다. 응답이 CloudFront 캐시에서 왔는지 오리진에서 왔는지는 관계없습니다. 예를 들어 함수 코드에서 응답 헤더, 상태 코드 및 본문 콘텐츠를 추가하거나 수정할 수 있습니다.

HTTP 응답을 수정하는 함수를 생성할 때는 *최종 사용자 응답* 이벤트 유형을 선택해야 합니다. 즉, 응답이 CloudFront 캐시에서 왔는지 오리진에서 왔는지 관계없이 CloudFront가 최종 사용자에게 응답을 반환하기 전에 함수가 실행됩니다.

**Example 예제**  
다음 유사 코드는 HTTP 응답을 수정하는 함수의 구조를 보여줍니다.  

```
function handler(event) {
    var request = event.request;
    var response = event.response;

    // Modify the response object here,
    // using the request properties if needed.

    return response;
}
```
이 함수는 수정된 `response` 객체를 CloudFront로 반환하며 CloudFront는 즉시 최종 사용자에게 반환합니다.

## 연결 요청 이벤트 유형에서 mTLS 연결 검증
<a name="function-code-connection-request"></a>

연결 함수는 사용자 지정 검증 및 인증 로직을 제공하기 위해 TLS 연결 중에 실행되는 CloudFront Functions의 한 유형입니다. 연결 함수는 현재 상호 TLS(mTLS) 연결에 사용할 수 있으며, 여기서 클라이언트 인증서를 검증하고 표준 인증서 검증을 넘어 사용자 지정 인증 로직을 구현할 수 있습니다. 연결 함수는 TLS 핸드셰이크 프로세스 중에 실행되며 인증서 속성, 클라이언트 IP 주소 또는 기타 기준에 따라 연결을 허용하거나 거부할 수 있습니다.

연결 함수를 생성하고 게시한 후에는 mTLS 지원 배포에 *연결 요청* 이벤트 유형에 대한 연결을 추가해야 합니다. 이렇게 하면 클라이언트가 CloudFront와 mTLS 연결을 설정하려고 할 때마다 함수가 실행됩니다.

**Example**  
다음 의사 코드는 연결 함수의 구조를 보여줍니다.  

```
function connectionHandler(connection) {
    // Validate certificate and connection properties here.
    
    if (/* validation passes */) {
        connection.allow();
    } else {
        connection.deny();
    }
}
```
함수는 헬퍼 메서드를 사용하여 연결을 허용할지 거부할지를 결정합니다. 뷰어 요청 및 뷰어 응답 함수와 달리 연결 함수는 HTTP 요청 또는 응답을 수정할 수 없습니다.

## 관련 정보
<a name="related-information-cloudfront-functions-purpose"></a>

CloudFront Functions 작업에 대한 자세한 내용은 다음 주제를 참조하세요.
+ [이벤트 구조](functions-event-structure.md)
+ [JavaScript 런타임 기능](functions-javascript-runtime-features.md)
+ [CloudFront Functions 예제 ](service_code_examples_cloudfront_functions_examples.md)
+ [엣지 함수에 대한 제한 사항](edge-functions-restrictions.md)

# CloudFront 함수 이벤트 구조
<a name="functions-event-structure"></a>

CloudFront 함수는 함수를 실행할 때 `event` 객체를 함수 코드에 입력으로 전달합니다. [함수를 테스트](test-function.md)할 때 `event` 객체를 생성하여 함수에 전달합니다. 함수를 테스트하기 위해 `event` 객체를 생성할 때 `distributionDomainName` 객체의 `distributionId`, `requestId` 및 `context` 필드를 생략할 수 있습니다. 헤더의 이름이 소문자인지 확인합니다. CloudFront Functions가 프로덕션 환경에서 함수에 전달하는 `event` 객체의 경우 항상 소문자입니다.

다음은 이 이벤트 객체의 구조에 대한 개요를 보여 줍니다.

```
{
    "version": "1.0",
    "context": {
        <context object>
    },
    "viewer": {
        <viewer object>
    },
    "request": {
        <request object>
    },
    "response": {
        <response object>
    }
}
```

자세한 내용은 다음 항목을 참조하세요.

**Topics**
+ [

## 버전 필드
](#functions-event-structure-version)
+ [

## 컨텍스트 객체
](#functions-event-structure-context)
+ [

## 연결 이벤트 구조
](#functions-event-structure-connection)
+ [

## 최종 사용자 객체
](#functions-event-structure-viewer)
+ [

## 요청 객체
](#functions-event-structure-request)
+ [

## 응답 객체
](#functions-event-structure-response)
+ [

## 상태 코드 및 본문
](#functions-event-structure-status-body)
+ [

## 쿼리 문자열, 헤더 및 쿠키 구조
](#functions-event-structure-query-header-cookie)
+ [

## 예시 응답 객체
](#functions-response-structure-example)
+ [

## 예시 이벤트 객체
](#functions-event-structure-example)

## 버전 필드
<a name="functions-event-structure-version"></a>

`version` 필드에는 CloudFront 함수 이벤트 객체의 버전을 지정하는 문자열이 포함되어 있습니다. 현재 버전은 `1.0`입니다.

## 컨텍스트 객체
<a name="functions-event-structure-context"></a>

`context` 객체는 이벤트에 대한 컨텍스트 정보를 포함합니다. 여기에는 다음 필드가 포함됩니다.

**`distributionDomainName`**  
이벤트와 연결된 표준 배포의 CloudFront 도메인 이름(예: d111111abcdef8.cloudfront.net)입니다.  
`distributionDomainName` 필드는 함수가 표준 배포에서 호출될 때만 나타납니다.

**`endpoint`**  
이벤트와 연결된 연결 그룹의 CloudFront 도메인 이름(예: d111111abcdef8.cloudfront.net)입니다.  
`endpoint` 필드는 함수가 다중 테넌트 배포에서 호출될 때만 나타납니다.

**`distributionId`**  
이벤트와 연결된 배포의 ID(예: EDFDVBD6EXAMPLE)입니다.

**`eventType`**  
이벤트 유형(`viewer-request` 또는 `viewer-response`)입니다.

**`requestId`**  
CloudFront 요청(및 연결된 응답)을 고유하게 식별하는 문자열입니다.

## 연결 이벤트 구조
<a name="functions-event-structure-connection"></a>

연결 함수는 뷰어 함수와 다른 이벤트 구조를 수신합니다. 연결 이벤트 구조 및 응답 형식에 대한 자세한 내용은 [CloudFront 연결 함수 연결](connection-functions.md) 섹션을 참조하세요.

## 최종 사용자 객체
<a name="functions-event-structure-viewer"></a>

`viewer` 객체는 요청을 보낸 최종 사용자(클라이언트)의 IP 주소 값이 있는 `ip` 필드를 포함합니다. 최종 사용자가 HTTP 프록시 또는 로드 밸런서를 사용하여 요청을 전송한 경우 이 값은 프록시 또는 로드 밸런서의 IP 주소입니다.

## 요청 객체
<a name="functions-event-structure-request"></a>

`request` 객체는 viewer-to-CloudFront HTTP 요청의 표현을 포함합니다. 함수에 전달된 `event` 객체에서 `request` 객체는 CloudFront가 뷰어에게 받은 실제 요청을 나타냅니다.

함수 코드가 CloudFront에 `request` 객체를 반환하는 경우 동일한 구조를 사용해야 합니다.

`request` 객체는 다음 필드를 포함합니다.

**`method`**  
요청의 HTTP 메서드. 함수 코드가 `request`를 반환하면 이 필드를 수정할 수 없습니다. 이 필드는 `request` 객체에서 유일한 읽기 전용 필드입니다.

**`uri`**  
요청된 객체의 상대 경로입니다.  
함수가 `uri` 값을 수정하는 경우 다음 사항이 적용됩니다.  
+ 새 `uri` 값은 슬래시(`/`)로 시작해야 합니다.
+ 함수가 `uri` 값을 변경하는 경우 이로 인해 최종 사용자가 요청 중인 객체가 변경됩니다.
+ 함수가 `uri` 값을 변경하는 경우 이로 인해 요청 또는 요청이 전송되는 오리진에 대한 캐시 동작이 변경되지 **않습니다.

**`querystring`**  
요청의 쿼리 문자열을 나타내는 객체입니다. 요청에 쿼리 문자열이 포함되지 않더라도 `request` 객체에는 여전히 빈 `querystring` 객체가 포함됩니다.  
`querystring` 객체는 요청의 각 쿼리 문자열 파라미터에 대해 하나의 필드를 포함합니다.

**`headers`**  
요청의 HTTP 헤더를 나타내는 객체입니다. 요청에 `Cookie` 헤더가 포함되어 있으면 해당 헤더는 `headers` 객체의 일부가 아닙니다. 쿠키는 `cookies` 객체에서 별도로 표시됩니다.  
`headers` 객체는 요청의 각 헤더에 대해 하나의 필드를 포함합니다. 헤더 이름은 이벤트 객체에서 ASCII 소문자로 변환되므로 함수 코드에서 추가될 경우 헤더 이름은 ASCII 소문자여야 합니다. CloudFront Functions이 이벤트 객체를 HTTP 요청으로 다시 변환할 경우 헤더 이름이 ASCII 문자이면 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. CloudFront Functions은 헤더 이름의 ASCII가 아닌 기호에 변경 사항을 적용하지 않습니다. 예를 들어 `TÈst-header`는 함수 내 `tÈst-header`에 있게 됩니다. ASCII가 아닌 기호(`È`)는 변경되지 않습니다.  
단어는 하이픈(`-`)으로 구분됩니다. 예를 들어 함수 코드가 `example-header-name`이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 요청에서 `Example-Header-Name`으로 변환합니다.

**`cookies`**  
요청(`Cookie` 헤더)의 쿠키를 나타내는 객체입니다.  
`cookies` 객체는 요청의 각 쿠키에 대해 하나의 필드를 포함합니다.

쿼리 문자열, 헤더 및 쿠키의 구조에 대한 자세한 내용은 [쿼리 문자열, 헤더 및 쿠키 구조](#functions-event-structure-query-header-cookie) 단원을 참조하세요.

예제 `event` 객체에 대해서는 [예시 이벤트 객체](#functions-event-structure-example) 단원을 참조하세요.

## 응답 객체
<a name="functions-event-structure-response"></a>

`response` 객체는 CloudFront-to-Viewer HTTP 응답의 표현을 포함합니다. 함수에 전달된 `event` 객체에서 `response` 객체는 뷰어 요청에 대한 CloudFront의 실제 응답을 나타냅니다.

함수 코드가 `response` 객체를 반환하는 경우 이 동일한 구조를 사용해야 합니다.

`response` 객체는 다음 필드를 포함합니다.

**`statusCode`**  
응답의 HTTP 상태 코드입니다. 이 값은 문자열이 아닌 정수입니다.  
함수는 `statusCode`를 생성하거나 수정할 수 있습니다.

**`statusDescription`**  
응답의 HTTP 상태 설명입니다. 함수 코드에서 응답을 생성하는 경우 이 필드는 선택 사항입니다.

**`headers`**  
응답에서 HTTP 헤더를 나타내는 객체입니다. 응답에 `Set-Cookie` 헤더가 포함되어 있으면 해당 헤더는 `headers` 객체의 일부가 아닙니다. 쿠키는 `cookies` 객체에서 별도로 표시됩니다.  
`headers` 객체는 응답의 각 헤더에 대해 하나의 필드를 포함합니다. 헤더 이름은 이벤트 객체에서 소문자로 변환되므로, 헤더 이름은 함수 코드에 의해 추가될 때 소문자여야 합니다. CloudFront 함수가 이벤트 객체를 HTTP 응답으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈(`-`)으로 구분됩니다. 예를 들어 함수 코드가 `example-header-name`이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 응답에서 `Example-Header-Name`으로 변환합니다.

**`cookies`**  
응답(`Set-Cookie` 헤더)에서 쿠키를 나타내는 객체입니다.  
`cookies` 객체는 응답의 각 쿠키에 대해 하나의 필드를 포함합니다.

**`body`**  
`body` 필드 추가는 선택 사항이며 함수에서 지정하지 않는 한 `response` 객체에 표시되지 않습니다. 함수는 CloudFront 캐시 또는 오리진에서 반환된 원래 본문에 액세스할 수 없습니다. 뷰어 응답 함수에서 `body` 필드를 지정하지 않으면 CloudFront 캐시 또는 오리진에서 반환되는 원래 본문이 뷰어에게 반환됩니다.  
CloudFront에서 뷰어에게 사용자 지정 본문을 반환하도록 하려면 `data` 필드에 본문 콘텐츠를 지정하고 `encoding` 필드에 본문 인코딩을 지정하세요. 인코딩을 일반 텍스트(`"encoding": "text"`) 또는 Base64로 인코딩된 콘텐츠(`"encoding": "base64"`)로 지정할 수 있습니다.  
단축키로 `body` 필드(`"body": "<specify the body content here>"`)에서 직접 본문 콘텐츠를 지정할 수도 있습니다. 이 작업을 수행할 때는 `data` 및 `encoding` 필드를 생략하세요. 이 경우 CloudFront는 본문을 일반 텍스트로 취급합니다.    
`encoding`  
`body` 콘텐츠(`data`필드)의 인코딩입니다. 유일하게 유효한 인코딩은 `text`과 `base64`입니다.  
`encoding`을 `base64`로 지정하지만 본문이 유효한 base64가 아닌 경우 CloudFront는 오류를 반환합니다.  
`data`  
`body` 콘텐츠입니다.

수정된 상태 코드 및 본문 콘텐츠에 대한 자세한 내용은 [상태 코드 및 본문](#functions-event-structure-status-body)를 참조하세요.

헤더 및 쿠키의 구조에 대한 자세한 내용은 [쿼리 문자열, 헤더 및 쿠키 구조](#functions-event-structure-query-header-cookie) 단원을 참조하세요.

예제 `response` 객체에 대해서는 [예시 응답 객체](#functions-response-structure-example) 단원을 참조하세요.

## 상태 코드 및 본문
<a name="functions-event-structure-status-body"></a>

CloudFront Functions를 사용하여 뷰어 응답 상태 코드를 업데이트하고 응답 본문 전체를 새것으로 바꾸거나 제거할 수 있습니다. CloudFront 캐시 또는 오리진에서 응답의 여러 측면을 평가한 후 뷰어 응답을 업데이트하는 일반적인 시나리오는 다음과 같습니다.
+ 상태를 변경하여 HTTP 200 상태 코드를 설정하고 정적 본문 콘텐츠를 생성하여 뷰어에게 반환합니다.
+ 상태를 변경하여 HTTP 301 또는 302 상태 코드를 설정하고 사용자를 다른 웹 페이지로 리디렉션합니다.
+ 뷰어 응답의 본문을 제공할지 아니면 삭제할지 결정합니다.

**참고**  
오리진에서 400 이상의 HTTP 오류를 반환하는 경우 CloudFront Function이 실행되지 않습니다. 자세한 내용은 [모든 엣지 함수에 대한 제한 사항](edge-function-restrictions-all.md)을 참조하세요.

HTTP 응답 본문을 사용하여 작업 중일 때 CloudFront Functions가 응답 본문에 액세스하지 못합니다. 원하는 값으로 설정하여 본문 콘텐츠를 바꾸거나 값을 비어 있음으로 설정하여 본문을 제거할 수 있습니다. 함수의 본문 필드를 업데이트하지 않은 경우 CloudFront 캐시 또는 오리진에서 반환된 원래 본문이 뷰어에게 반환됩니다.

**작은 정보**  
CloudFront Functions를 사용하여 본문을 교체하는 경우`content-encoding`, `content-type` 또는 `content-length` 등의 해당 헤더를 새 본문 콘텐츠에 맞게 정렬해야 합니다.  
예를 들어 CloudFront 오리진 또는 캐시가 `content-encoding: gzip`을 반환하지만 뷰어 응답 함수가 일반 텍스트인 본문을 설정하는 경우 함수는 `content-encoding` 및 `content-type` 헤더도 그에 따라 변경해야 합니다.

CloudFront Function이 400 이상의 HTTP 오류를 반환하도록 구성된 경우 동일한 상태 코드에 대해 지정한 [사용자 지정 오류 페이지](creating-custom-error-pages.md)가 뷰어에게 표시되지 않습니다.

## 쿼리 문자열, 헤더 및 쿠키 구조
<a name="functions-event-structure-query-header-cookie"></a>

쿼리 문자열, 헤더 및 쿠키는 동일한 구조를 공유합니다. 쿼리 문자열은 요청에 표시될 수 있습니다. 헤더는 요청 및 응답에 표시됩니다. 쿠키는 요청 및 응답에 표시됩니다.

각 쿼리 문자열, 헤더 또는 쿠키는 상위 `querystring`, `headers` 또는 `cookies` 객체 내에서 고유한 필드입니다. 필드 이름은 쿼리 문자열, 헤더 또는 쿠키의 이름입니다. 각 필드에는 쿼리 문자열, 헤더 또는 쿠키의 값이 있는 `value` 속성이 포함됩니다.

**Contents**
+ [

### 쿼리 문자열 값 또는 쿼리 문자열 객체
](#functions-event-structure-query)
+ [

### 헤더에 대한 특별 고려 사항
](#functions-event-structure-headers)
+ [

### 중복 쿼리 문자열, 헤더 및 쿠키(`multiValue` 배열)
](#functions-event-structure-multivalue)
+ [

### 쿠키 속성
](#functions-event-structure-cookie-attributes)

### 쿼리 문자열 값 또는 쿼리 문자열 객체
<a name="functions-event-structure-query"></a>

함수는 쿼리 문자열 객체 외에도 쿼리 문자열 값을 반환할 수 있습니다. 쿼리 문자열 값을 사용하여 쿼리 문자열 파라미터를 사용자 지정 순서로 정렬할 수 있습니다.

**Example 예제**  
함수 코드에서 쿼리 문자열을 수정하려면 다음과 같은 코드를 사용합니다.  

```
var request = event.request; 
request.querystring = 'ID=42&Exp=1619740800&TTL=1440&NoValue=&querymv=val1&querymv=val2,val3';
```

### 헤더에 대한 특별 고려 사항
<a name="functions-event-structure-headers"></a>

헤더의 경우, 헤더 이름은 이벤트 객체에서 소문자로 변환되므로, 헤더 이름은 함수 코드에 의해 추가될 때 소문자여야 합니다. CloudFront 함수가 이벤트 객체를 HTTP 요청 또는 응답으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈(`-`)으로 구분됩니다. 예를 들어 함수 코드가 `example-header-name`이라는 이름의 헤더를 추가하는 경우, CloudFront는 이것을 HTTP 요청 또는 응답에서 `Example-Header-Name`으로 변환합니다.

**Example 예제**  
HTTP 요청에서 다음 `Host` 헤더를 고려합니다.  

```
Host: video.example.com
```
이 헤더는 `request` 객체에서 다음과 같이 표시됩니다.  

```
"headers": {
    "host": {
        "value": "video.example.com"
    }
}
```
함수 코드의 `Host` 헤더에 액세스하려면 다음과 같은 코드를 사용합니다.  

```
var request = event.request;
var host = request.headers.host.value;
```
함수 코드에서 헤더를 추가하거나 수정하려면 다음과 같은 코드를 사용합니다(이 코드는 `X-Custom-Header` 값이 있는 `example value`(이)라는 이름의 헤더를 추가함).  

```
var request = event.request;
request.headers['x-custom-header'] = {value: 'example value'};
```

### 중복 쿼리 문자열, 헤더 및 쿠키(`multiValue` 배열)
<a name="functions-event-structure-multivalue"></a>

HTTP 요청 또는 응답은 동일한 이름의 하나 이상의 쿼리 문자열, 헤더 또는 쿠키를 포함할 수 있습니다. 이 경우 중복 쿼리 문자열, 헤더 또는 쿠키가 `request` 또는 `response` 객체의 한 필드로 축소되지만 이 필드에는 `multiValue`(이)라는 추가 속성이 포함되어 있습니다. `multiValue` 속성에는 중복 쿼리 문자열, 헤더 또는 쿠키의 각 값이 포함된 배열이 포함됩니다.

**Example 예제**  
예를 들어 다음 `Accept` 헤더가 있는 HTTP 요청을 고려합니다.  

```
Accept: application/json
Accept: application/xml
Accept: text/html
```
이러한 헤더는 `request` 객체에 다음과 같이 표시됩니다.  

```
"headers": {
    "accept": {
        "value": "application/json",
        "multiValue": [
            {
                "value": "application/json"
            },
            {
                "value": "application/xml"
            },
            {
                "value": "text/html"
            }
        ]
    }
}
```

**참고**  
첫 번째 헤더 값(이 경우 `application/json`)은 `value` 및 `multiValue` 속성 모두에서 반복됩니다. 이렇게 하면 `multiValue` 배열을 반복하여 *모든* 값에 액세스할 수 있습니다.

함수 코드가 `multiValue` 배열이 있는 쿼리 문자열, 헤더 또는 쿠키를 수정하는 경우 CloudFront 함수는 다음 규칙을 사용하여 변경 사항을 적용합니다.

1. `multiValue` 배열이 존재하고 수정이 있으면 해당 수정이 적용됩니다. `value` 속성의 첫 번째 요소는 무시됩니다.

1. 그렇지 않으면 `value` 속성에 대한 수정 사항이 적용되고 후속 값(있는 경우)은 변경되지 않습니다.

`multiValue` 속성은 앞의 예제와 같이 HTTP 요청 또는 응답에 동일한 이름의 중복 쿼리 문자열, 헤더 또는 쿠키가 포함된 경우에만 사용됩니다. 그러나 단일 쿼리 문자열, 헤더 또는 쿠키에 값이 여러 개 있으면 `multiValue` 속성이 사용되지 않습니다.

**Example 예제**  
예를 들어 세 개의 값을 포함하는 하나의 `Accept` 헤더가 있는 요청을 고려합니다.  

```
Accept: application/json, application/xml, text/html
```
이 헤더는 `request` 객체에서 다음과 같이 표시됩니다.  

```
"headers": {
    "accept": {
        "value": "application/json, application/xml, text/html"
    }
}
```

### 쿠키 속성
<a name="functions-event-structure-cookie-attributes"></a>

HTTP 응답의 `Set-Cookie` 헤더에서 헤더에는 쿠키의 이름-값 쌍과 세미콜론으로 구분된 속성 집합이 포함됩니다.

**Example 예제**  

```
Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT
```
`response` 객체에서 이러한 속성은 쿠키 필드의 `attributes` 속성에 표시됩니다. 예를 들어, 앞의 `Set-Cookie` 헤더는 다음과 같이 표시됩니다.  

```
"cookie1": {
    "value": "val1",
    "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
}
```

## 예시 응답 객체
<a name="functions-response-structure-example"></a>

다음 예시는 본문이 뷰어 응답 함수로 대체된 `response` 객체(뷰어 응답 함수의 출력)를 보여줍니다.

```
{
  "response": {
    "statusCode": 200,
    "statusDescription": "OK",
    "headers": {
      "date": {
        "value": "Mon, 04 Apr 2021 18:57:56 GMT"
      },
      "server": {
        "value": "gunicorn/19.9.0"
      },
      "access-control-allow-origin": {
        "value": "*"
      },
      "access-control-allow-credentials": {
        "value": "true"
      },
      "content-type": {
        "value": "text/html"
      },
      "content-length": {
        "value": "86"
      }
    },
    "cookies": {
      "ID": {
        "value": "id1234",
        "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT"
      },
      "Cookie1": {
        "value": "val1",
        "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT",
        "multiValue": [
          {
            "value": "val1",
            "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
          },
          {
            "value": "val2",
            "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT"
          }
        ]
      }
    },
    
    // Adding the body field is optional and it will not be present in the response object
    // unless you specify it in your function.
    // Your function does not have access to the original body returned by the CloudFront
    // cache or origin.
    // If you don't specify the body field in your viewer response function, the original
    // body returned by the CloudFront cache or origin is returned to viewer.

     "body": {
      "encoding": "text",
      "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>"
    }
  }
}
```

## 예시 이벤트 객체
<a name="functions-event-structure-example"></a>

다음 예는 완전한 `event` 객체를 보여줍니다. 이 예제는 다중 테넌트 배포가 아닌 표준 배포에서의 호출입니다. 다중 테넌트 배포의 경우 `distributionDomainName` 대신 `endpoint` 필드가 사용됩니다. `endpoint`의 값은 이벤트와 연결된 연결 그룹의 CloudFront 도메인 이름(예: d111111abcdef8.cloudfront.net)입니다.

**참고**  
`event` 객체는 함수에 대한 입력입니다. 함수는 `request` 또는 `response` 객체만 반환하고 전체 `event` 객체는 반환하지 않습니다.

```
{
    "version": "1.0",
    "context": {
        "distributionDomainName": "d111111abcdef8.cloudfront.net",
        "distributionId": "EDFDVBD6EXAMPLE",
        "eventType": "viewer-response",
        "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE=="
    },
    "viewer": {"ip": "198.51.100.11"},
    "request": {
        "method": "GET",
        "uri": "/media/index.mpd",
        "querystring": {
            "ID": {"value": "42"},
            "Exp": {"value": "1619740800"},
            "TTL": {"value": "1440"},
            "NoValue": {"value": ""},
            "querymv": {
                "value": "val1",
                "multiValue": [
                    {"value": "val1"},
                    {"value": "val2,val3"}
                ]
            }
        },
        "headers": {
            "host": {"value": "video.example.com"},
            "user-agent": {"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"},
            "accept": {
                "value": "application/json",
                "multiValue": [
                    {"value": "application/json"},
                    {"value": "application/xml"},
                    {"value": "text/html"}
                ]
            },
            "accept-language": {"value": "en-GB,en;q=0.5"},
            "accept-encoding": {"value": "gzip, deflate, br"},
            "origin": {"value": "https://website.example.com"},
            "referer": {"value": "https://website.example.com/videos/12345678?action=play"},
            "cloudfront-viewer-country": {"value": "GB"}
        },
        "cookies": {
            "Cookie1": {"value": "value1"},
            "Cookie2": {"value": "value2"},
            "cookie_consent": {"value": "true"},
            "cookiemv": {
                "value": "value3",
                "multiValue": [
                    {"value": "value3"},
                    {"value": "value4"}
                ]
            }
        }
    },
    "response": {
        "statusCode": 200,
        "statusDescription": "OK",
        "headers": {
            "date": {"value": "Mon, 04 Apr 2021 18:57:56 GMT"},
            "server": {"value": "gunicorn/19.9.0"},
            "access-control-allow-origin": {"value": "*"},
            "access-control-allow-credentials": {"value": "true"},
            "content-type": {"value": "application/json"},
            "content-length": {"value": "701"}
        },
        "cookies": {
            "ID": {
                "value": "id1234",
                "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT"
            },
            "Cookie1": {
                "value": "val1",
                "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT",
                "multiValue": [
                    {
                        "value": "val1",
                        "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
                    },
                    {
                        "value": "val2",
                        "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT"
                    }
                ]
            }
        }
    }
}
```

# CloudFront 함수에 대한 JavaScript 런타임 기능
<a name="functions-javascript-runtime-features"></a>

CloudFront Functions JavaScript 런타임 환경은 [ECMAScript(ES) 버전 5.1](https://www.ecma-international.org/ecma-262/5.1/)을 준수하며, ES 버전 6에서 12까지의 일부 기능을 지원합니다.

최신 기능을 이용하려면 JavaScript 런타임 2.0을 사용하는 것이 좋습니다.

JavaScript 1.0과 비교한 JavaScript 2.0의 변경 사항은 다음과 같습니다.
+ 버퍼 모듈 메서드 사용 가능
+ 다음과 같은 비표준 문자열 프로토타입 메서드는 사용할 수 없습니다.
  + `String.prototype.bytesFrom()`
  + `String.prototype.fromBytes()`
  + `String.prototype.fromUTF8()`
  + `String.prototype.toBytes()`
  + `String.prototype.toUTF8()`
+ 암호화 모듈의 변경 사항은 다음과 같습니다.
  + `hash.digest()` - 인코딩이 제공되지 않은 경우 반환 유형이 `Buffer`로 변경됩니다.
  + `hmac.digest()` - 인코딩이 제공되지 않은 경우 반환 유형이 `Buffer`로 변경됩니다.
+ 이 밖의 새로운 기능에 대한 자세한 내용은 [CloudFront Functions를 위한 JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md) 섹션을 참조하세요.

**Topics**
+ [JavaScript 런타임 1.0 기능](functions-javascript-runtime-10.md)
+ [JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md)

# CloudFront Functions를 위한 JavaScript 런타임 1.0 기능
<a name="functions-javascript-runtime-10"></a>

CloudFront 함수 JavaScript 런타임 환경은 [ECMAScript(ES) 버전 5.1](https://262.ecma-international.org/5.1/)을 준수하며, ES 버전 6에서 9까지의 일부 기능을 지원합니다. 또한 ES 사양의 일부가 아닌 일부 비표준 방법을 제공합니다.

다음 항목에는 지원되는 모든 언어 기능이 나열되어 있습니다.

**Topics**
+ [

## 핵심 기능
](#writing-functions-javascript-features-core)
+ [

## 기본 객체
](#writing-functions-javascript-features-primitive-objects)
+ [

## 기본 제공 객체
](#writing-functions-javascript-features-builtin-objects)
+ [

## 오류 유형
](#writing-functions-javascript-features-error-types)
+ [

## Globals
](#writing-functions-javascript-features-globals)
+ [

## 기본 제공 모듈
](#writing-functions-javascript-features-builtin-modules)
+ [

## 제한된 기능
](#writing-functions-javascript-features-restricted-features)

## 핵심 기능
<a name="writing-functions-javascript-features-core"></a>

ES의 다음과 같은 핵심 기능이 지원됩니다.

**유형**  
모든 ES 5.1 유형이 지원됩니다. 여기에는 부울 값, 숫자, 문자열, 객체, 배열, 함수, 함수 생성자 및 정규 표현식이 포함됩니다.

**연산자**  
모든 ES 5.1 연산자가 지원됩니다.  
ES 7 거듭제곱 연산자(`**`)가 지원됩니다.

**Statement**  
`const` 및 `let` 문은 지원되지 않습니다.
다음 ES 5.1 문이 지원됩니다.  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
+ 레이블이 지정된 명령문

**리터럴**  
ES 6 템플릿 리터럴은 여러 줄 문자열, 표현식 보간 및 중첩 템플릿에 대해 지원됩니다..

**함수**  
모든 ES 5.1 함수 기능이 지원됩니다.  
ES 6 화살표 함수가 지원되며 ES 6 나머지 파라미터 구문이 지원됩니다.

**유니코드**  
소스 텍스트 및 문자열 리터럴에는 유니코드로 인코딩된 문자가 포함될 수 있습니다. 6자의 유니코드 코드 포인트 이스케이프 시퀀스(예: `\uXXXX`)도 지원됩니다.

**엄격 모드**  
함수는 기본적으로 엄격 모드에서 작동하므로 함수 코드에 `use strict` 명령문을 추가할 필요가 없습니다. 이것은 변경할 수 없습니다.

## 기본 객체
<a name="writing-functions-javascript-features-primitive-objects"></a>

ES의 다음과 같은 기본 객체가 지원됩니다.

**객체**  
객체에 대해 다음과 같은 ES 5.1 메서드가 지원됩니다.  
+ `create`(속성 목록 제외)
+ `defineProperties`
+ `defineProperty`
+ `freeze`
+ `getOwnPropertyDescriptor`
+ `getOwnPropertyNames`
+ `getPrototypeOf`
+ `hasOwnProperty`
+ `isExtensible`
+ `isFrozen`
+ `prototype.isPrototypeOf`
+ `isSealed`
+ `keys`
+ `preventExtensions`
+ `prototype.propertyIsEnumerable`
+ `seal`
+ `prototype.toString`
+ `prototype.valueOf`
객체에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `assign`
+ `is`
+ `prototype.setPrototypeOf`
객체에 대해 다음과 같은 ES 8 메서드가 지원됩니다.  
+ `entries`
+ `values`

**문자열**  
문자열에 대해 다음 ES 5.1 메서드가 지원됩니다.  
+ `fromCharCode`
+ `prototype.charAt`
+ `prototype.concat`
+ `prototype.indexOf`
+ `prototype.lastIndexOf`
+ `prototype.match`
+ `prototype.replace`
+ `prototype.search`
+ `prototype.slice`
+ `prototype.split`
+ `prototype.substr`
+ `prototype.substring`
+ `prototype.toLowerCase`
+ `prototype.trim`
+ `prototype.toUpperCase`
문자열에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `fromCodePoint`
+ `prototype.codePointAt`
+ `prototype.endsWith`
+ `prototype.includes`
+ `prototype.repeat`
+ `prototype.startsWith`
문자열에 대해 다음 ES 8 메서드가 지원됩니다.  
+ `prototype.padStart`
+ `prototype.padEnd`
문자열에 대해 다음 ES 9 메서드가 지원됩니다.  
+ `prototype.trimStart`
+ `prototype.trimEnd`
문자열에 대해 다음과 같은 비표준 메서드가 지원됩니다.  
+ `prototype.bytesFrom(array | string, encoding)`

  옥텟 배열 또는 인코딩된 문자열에서 바이트 문자열을 만듭니다. 문자열 인코딩 옵션은 `hex`, `base64` 및 `base64url`입니다.
+ `prototype.fromBytes(start[, end])`

  각 바이트가 해당 유니코드 코드 포인트로 대체되는 바이트 문자열에서 유니코드 문자열을 만듭니다.
+ `prototype.fromUTF8(start[, end])`

  UTF-8 인코딩된 바이트 문자열에서 유니코드 문자열을 만듭니다. 인코딩이 올바르지 않으면 `null`이(가) 반환됩니다.
+ `prototype.toBytes(start[, end])`

  유니코드 문자열에서 바이트 문자열을 만듭니다. 모든 문자는 [0,255] 범위에 있어야 합니다. 그렇지 않은 경우 `null`이 반환됩니다.
+ `prototype.toUTF8(start[, end])`

  유니코드 문자열에서 UTF-8 인코딩된 바이트 문자열을 만듭니다.

**번호**  
숫자에 대한 모든 ES 5.1 메서드가 지원됩니다.  
숫자에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `isFinite`
+ `isInteger`
+ `isNaN`
+ `isSafeInteger`
+ `parseFloat`
+ `parseInt`
+ `prototype.toExponential`
+ `prototype.toFixed`
+ `prototype.toPrecision`
+ `EPSILON`
+ `MAX_SAFE_INTEGER`
+ `MAX_VALUE`
+ `MIN_SAFE_INTEGER`
+ `MIN_VALUE`
+ `NEGATIVE_INFINITY`
+ `NaN`
+ `POSITIVE_INFINITY`

## 기본 제공 객체
<a name="writing-functions-javascript-features-builtin-objects"></a>

ES의 다음 내장 객체가 지원됩니다.

**수학 연산**  
모든 ES 5.1 수학 메서드가 지원됩니다.  
CloudFront 함수 런타임 환경에서 `Math.random()` 구현은 함수가 실행될 때의 타임스탬프와 함께 시드된 OpenBSD `arc4random`을(를) 사용합니다.
다음 ES 6 수학 메서드가 지원됩니다.  
+ `acosh`
+ `asinh`
+ `atanh`
+ `cbrt`
+ `clz32`
+ `cosh`
+ `expm1`
+ `fround`
+ `hypot`
+ `imul`
+ `log10`
+ `log1p`
+ `log2`
+ `sign`
+ `sinh`
+ `tanh`
+ `trunc`
+ `E`
+ `LN10`
+ `LN2`
+ `LOG10E`
+ `LOG2E`
+ `PI`
+ `SQRT1_2`
+ `SQRT2`

**날짜**  
모든 ES 5.1 `Date` 기능이 지원됩니다.  
보안상의 이유로 단일 함수 실행의 수명 동안 `Date`은(는) 항상 동일한 값(함수의 시작 시간)을 반환합니다. 자세한 내용은 [제한된 기능](#writing-functions-javascript-features-restricted-features) 단원을 참조하세요.

**함수**  
`apply`, `bind` 및 `call` 메서드가 지원됩니다.  
함수 생성자는 지원되지 않습니다.

**정규식**  
모든 ES 5.1 정규 표현식 기능이 지원됩니다. 정규 표현식 언어는 Perl과 호환됩니다. ES 9 명명된 캡처 그룹이 지원됩니다.

**JSON**  
`parse` 및 `stringify`을(를) 포함하여 모든 ES 5.1 JSON 기능이 지원됩니다.

**배열**  
배열에 대해 다음 ES 5.1 메서드가 지원됩니다.  
+ `isArray`
+ `prototype.concat`
+ `prototype.every`
+ `prototype.filter`
+ `prototype.forEach`
+ `prototype.indexOf`
+ `prototype.join`
+ `prototype.lastIndexOf`
+ `prototype.map`
+ `prototype.pop`
+ `prototype.push`
+ `prototype.reduce`
+ `prototype.reduceRight`
+ `prototype.reverse`
+ `prototype.shift`
+ `prototype.slice`
+ `prototype.some`
+ `prototype.sort`
+ `prototype.splice`
+ `prototype.unshift`
배열에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `of`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.find`
+ `prototype.findIndex`
배열에 대해 다음 ES 7 메서드가 지원됩니다.  
+ `prototype.includes`

**형식화된 배열**  
다음 ES 6 형식화된 배열이 지원됩니다.  
+ `Int8Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Int16Array`
+ `Uint16Array`
+ `Int32Array`
+ `Uint32Array`
+ `Float32Array`
+ `Float64Array`
+ `prototype.copyWithin`
+ `prototype.fill`
+ `prototype.join`
+ `prototype.set`
+ `prototype.slice`
+ `prototype.subarray`
+ `prototype.toString`

**배열 버퍼**  
`ArrayBuffer`에 대해 메서드가 지원됩니다.  
+ `prototype.isView`
+ `prototype.slice`

**Promise**  
Promise에 대해 다음 메서드가 지원됩니다.  
+ `reject`
+ `resolve`
+ `prototype.catch`
+ `prototype.finally`
+ `prototype.then`

**crypto**  
암호화 모듈은 표준 해싱 및 HMAC(해시 기반 메시지 인증 코드) 헬퍼를 제공합니다. `require('crypto')`을(를) 사용하여 모듈을 로드할 수 있습니다. 모듈은 해당 Node.js 대응으로 정확하게 동작하는 다음과 같은 메서드를 노출합니다.  
+ `createHash(algorithm)`
+ `hash.update(data)`
+ `hash.digest([encoding])`
+ `createHmac(algorithm, secret key)`
+ `hmac.update(data)`
+ `hmac.digest([encoding])`
자세한 내용은 기본 제공 모듈 단원의 [암호화(해시 및 HMAC)](#writing-functions-javascript-features-builtin-modules-crypto)를 참조하세요.

**콘솔**  
디버깅을 위한 헬퍼 객체입니다. 로그 메시지를 기록하는 `log()` 메서드만 지원합니다.  
CloudFront 함수는 `console.log('a', 'b')`와 같은 쉼표 구문을 지원하지 않습니다. 대신 `console.log('a' + ' ' + 'b')` 형식을 사용합니다.

## 오류 유형
<a name="writing-functions-javascript-features-error-types"></a>

다음과 같은 오류 객체가 지원됩니다.
+ `Error`
+ `EvalError`
+ `InternalError`
+ `MemoryError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals"></a>

`globalThis` 객체가 지원됩니다.

다음 ES 5.1 전역 함수가 지원됩니다.
+ `decodeURI`
+ `decodeURIComponent`
+ `encodeURI`
+ `encodeURIComponent`
+ `isFinite`
+ `isNaN`
+ `parseFloat`
+ `parseInt`

다음과 같은 글로벌 제약이 지원됩니다.
+ `NaN`
+ `Infinity`
+ `undefined`

## 기본 제공 모듈
<a name="writing-functions-javascript-features-builtin-modules"></a>

다음 기본 제공 모듈이 지원됩니다.

**Topics**
+ [

### 암호화(해시 및 HMAC)
](#writing-functions-javascript-features-builtin-modules-crypto)
+ [

### 쿼리 문자열
](#writing-functions-javascript-features-builtin-modules-query-string)

### 암호화(해시 및 HMAC)
<a name="writing-functions-javascript-features-builtin-modules-crypto"></a>

암호화 모듈(`crypto`)은 표준 해싱 및 HMAC(해시 기반 메시지 인증 코드) 헬퍼를 제공합니다. `require('crypto')`을(를) 사용하여 모듈을 로드할 수 있습니다. 이 모듈은 Node.js 대응물과 정확히 동일하게 동작하는 다음과 같은 메서드를 제공합니다.

**해싱 메서드**

`crypto.createHash(algorithm)`  
지정된 알고리즘(`md5`, `sha1` 또는 `sha256`)을 사용하여 해시 다이제스트를 생성하는 데 사용할 수 있는 해시 객체를 생성하고 반환합니다.

`hash.update(data)`  
지정된 `data`(으)로 해시 콘텐츠를 업데이트합니다.

`hash.digest([encoding])`  
`hash.update()`을(를) 사용하여 전달된 모든 데이터의 다이제스트를 계산합니다. 인코딩은 `hex`, `base64` 또는 `base64url`일 수 있습니다.

**HMAC 메서드**

`crypto.createHmac(algorithm, secret key)`  
지정된 `algorithm` 및 `secret key`을(를) 사용하는 HMAC 객체를 생성 및 반환합니다. 알고리즘은 `md5`, `sha1` 또는 `sha256`일 수 있습니다.

`hmac.update(data)`  
지정된 `data`(으)로 HMAC 콘텐츠를 업데이트합니다.

`hmac.digest([encoding])`  
`hmac.update()`을(를) 사용하여 전달된 모든 데이터의 다이제스트를 계산합니다. 인코딩은 `hex`, `base64` 또는 `base64url`일 수 있습니다.

### 쿼리 문자열
<a name="writing-functions-javascript-features-builtin-modules-query-string"></a>

**참고**  
[CloudFront 함수 이벤트 객체](functions-event-structure.md)는 URL 쿼리 문자열을 자동으로 구문 분석합니다. 즉, 대부분의 경우 이 모듈을 사용할 필요가 없습니다.

쿼리 문자열 모듈(`querystring`)은 URL 쿼리 문자열을 구문 분석하고 서식을 지정하는 메서드를 제공합니다. `require('querystring')`을 사용하여 모듈을 로드할 수 있습니다. 이 모듈은 다음과 같은 방법을 제공합니다.

`querystring.escape(string)`  
지정된 `string`을 URL-인코딩하여 이스케이프된 쿼리 문자열을 반환합니다. 이 방법은 `querystring.stringify()`에서 사용되며 직접 사용해서는 안 됩니다.

`querystring.parse(string[, separator[, equal[, options]]])`  
쿼리 문자열(`string`)을 구문 분석하고 객체를 반환합니다.  
`separator` 파라미터는 쿼리 문자열에서 키와 값 페어를 구분하기 위한 하위 문자열입니다. 기본 설정은 `&`입니다.  
`equal` 파라미터는 쿼리 문자열에서 키와 값을 구분하기 위한 하위 문자열입니다. 기본 설정은 `=`입니다.  
`options` 파라미터는 다음 키를 가진 객체입니다.    
`decodeURIComponent function`  
쿼리 문자열에서 백분율로 인코딩된 문자를 디코딩하는 함수입니다. 기본 설정은 `querystring.unescape()`입니다.  
`maxKeys number`  
구문 분석할 최대 키 수입니다. 기본 설정은 `1000`입니다. `0` 값을 사용하여 키 카운트 제한을 제거합니다.
기본적으로 쿼리 문자열 내의 백분율로 인코딩된 문자는 UTF-8 인코딩을 사용하는 것으로 간주됩니다. 잘못된 UTF-8 시퀀스는 `U+FFFD` 대체 문자로 대체됩니다.  
예를 들어 다음 쿼리 문자열의 경우:  

```
'name=value&abc=xyz&abc=123'
```
`querystring.parse()`의 반환 값:  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()`는 `querystring.parse()`의 별칭입니다.

`querystring.stringify(object[, separator[, equal[, options]]])`  
`object`를 직렬화하고 쿼리 문자열을 반환합니다.  
`separator` 파라미터는 쿼리 문자열에서 키와 값 쌍을 구분하기 위한 하위 문자열입니다. 기본 설정은 `&`입니다.  
`equal` 파라미터는 쿼리 문자열에서 키와 값을 구분하기 위한 하위 문자열입니다. 기본 설정은 `=`입니다.  
`options` 파라미터는 다음 키를 가진 객체입니다.    
`encodeURIComponent function`  
URL에 안전하지 않은 문자를 쿼리 문자열에서 백분율 인코딩으로 변환하는 데 사용할 함수입니다. 기본 설정은 `querystring.escape()`입니다.
기본적으로 쿼리 문자열 내에서 백분율 인코딩이 필요한 문자는 UTF-8로 인코딩됩니다. 다른 인코딩을 사용하려면 `encodeURIComponent` 옵션을 지정합니다.  
예를 들어, 다음 코드의 경우:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
반환 값:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()`는 `querystring.stringify()`의 별칭입니다.

`querystring.unescape(string)`  
지정된 `string`의 URL 백분율로 인코딩된 문자를 디코딩하여 이스케이프되지 않은 쿼리 문자열을 반환합니다. 이 방법은 `querystring.parse()`에서 사용되며 직접 사용해서는 안 됩니다.

## 제한된 기능
<a name="writing-functions-javascript-features-restricted-features"></a>

다음 JavaScript 언어 기능은 보안 문제로 인해 지원되지 않거나 제한됩니다.

**동적 코드 평가**  
동적 코드 평가는 지원되지 않습니다. 시도하면 `eval()` 및 `Function` 생성자 모두 오류가 발생합니다. 예를 들어 `const sum = new Function('a', 'b', 'return a + b')`에서 오류가 발생합니다.

**타이머**  
`setTimeout()`, `setImmediate()` 및 `clearTimeout()` 함수는 지원되지 않습니다. 함수 실행 내에서 연기하거나 출력할 프로비전이 없습니다. 함수가 완료되려면 동기적으로 실행되어야 합니다.

**날짜 및 타임스탬프**  
보안상의 이유로 고해상도 타이머에 액세스할 수 없습니다. 현재 시간을 쿼리하는 모든 `Date` 메서드는 단일 함수 실행의 수명 동안 항상 동일한 값을 반환합니다. 반환된 타임 스탬프는 함수가 실행을 시작한 시간입니다. 따라서 함수에서 경과 시간을 측정할 수 없습니다.

**파일 시스템 액세스**  
파일 시스템 액세스가 없습니다. 예를 들어 Node.js에서처럼 파일 시스템 액세스를 위한 `fs` 모듈이 없습니다.

**프로세스 액세스**  
프로세스 액세스가 없습니다. 예를 들어 Node.js와는 달리 정보 액세스를 처리하기 위한 `process` 글로벌 객체가 없습니다.

**환경 변수**  
환경 변수에 액세스할 수 없습니다.  
대신 CloudFront KeyValueStore를 사용하여 CloudFront Functions에 대한 키 값 페어의 중앙 집중식 데이터 스토어를 생성할 수 있습니다. CloudFront KeyValueStore를 사용하면 코드 변경 사항을 배포할 필요 없이 구성 데이터를 동적으로 업데이트할 수 있습니다. CloudFront KeyValueStore를 사용하려면 [JavaScript 런타임 2.0](functions-javascript-runtime-20.md)을 사용해야 합니다. 자세한 내용은 [Amazon CloudFront KeyValueStore](kvs-with-functions.md) 섹션을 참조하세요.

**네트워크 액세스**  
네트워크 통화에 대한 지원이 없습니다. 예를 들어 XHR, HTTP(S) 및 소켓은 지원되지 않습니다.

# CloudFront Functions를 위한 JavaScript 런타임 2.0 기능
<a name="functions-javascript-runtime-20"></a>

CloudFront Functions JavaScript 런타임 환경은 [ECMAScript(ES) 버전 5.1](https://262.ecma-international.org/5.1/)을 준수하며, ES 버전 6에서 12까지의 일부 기능을 지원합니다. 또한 ES 사양의 일부가 아닌 일부 비표준 방법을 제공합니다. 다음 주제에는 이 런타임에서 지원되는 모든 기능이 나열되어 있습니다.

**Topics**
+ [

## 핵심 기능
](#writing-functions-javascript-features-core-20)
+ [

## 기본 객체
](#writing-functions-javascript-features-primitive-objects-20)
+ [

## 기본 제공 객체
](#writing-functions-javascript-features-builtin-objects-20)
+ [

## 오류 유형
](#writing-functions-javascript-features-error-types-20)
+ [

## Globals
](#writing-functions-javascript-features-globals-20)
+ [

## 기본 제공 모듈
](#writing-functions-javascript-features-builtin-modules-20)
+ [

## 제한된 기능
](#writing-functions-javascript-features-restricted-features-20)

## 핵심 기능
<a name="writing-functions-javascript-features-core-20"></a>

ES의 다음과 같은 핵심 기능이 지원됩니다.

**유형**  
모든 ES 5.1 유형이 지원됩니다. 여기에는 부울 값, 숫자, 문자열, 객체, 배열, 함수, 정규 표현식이 포함됩니다.

**연산자**  
모든 ES 5.1 연산자가 지원됩니다.  
ES 7 거듭제곱 연산자(`**`)가 지원됩니다.

**Statement**  
다음 ES 5.1 문이 지원됩니다.  
+ `break`
+ `catch`
+ `continue`
+ `do-while`
+ `else`
+ `finally`
+ `for`
+ `for-in`
+ `if`
+ `label`
+ `return`
+ `switch`
+ `throw`
+ `try`
+ `var`
+ `while`
다음 ES 6 문이 지원됩니다.  
+ `const`
+ `let`
다음 ES 8 문이 지원됩니다.  
+ `async`
+ `await`
`async`, `await`, `const` 및 `let`가 JavaScript 런타임 2.0에서 지원됩니다.  
`await`는 `async` 함수 내에서만 사용할 수 있습니다. `async` 인수 및 종료는 지원되지 않습니다.

**리터럴**  
ES 6 템플릿 리터럴은 여러 줄 문자열, 표현식 보간 및 중첩 템플릿에 대해 지원됩니다..

**함수**  
모든 ES 5.1 함수 기능이 지원됩니다.  
ES 6 화살표 함수가 지원되며 ES 6 나머지 파라미터 구문이 지원됩니다.

**유니코드**  
소스 텍스트 및 문자열 리터럴에는 유니코드로 인코딩된 문자가 포함될 수 있습니다. 6자의 유니코드 코드 포인트 이스케이프 시퀀스(예: `\uXXXX`)도 지원됩니다.

**엄격 모드**  
함수는 기본적으로 엄격 모드에서 작동하므로 함수 코드에 `use strict` 명령문을 추가할 필요가 없습니다. 이것은 변경할 수 없습니다.

## 기본 객체
<a name="writing-functions-javascript-features-primitive-objects-20"></a>

ES의 다음과 같은 기본 객체가 지원됩니다.

**객체**  
객체에 대해 다음과 같은 ES 5.1 메서드가 지원됩니다.  
+ `Object.create()`(속성 목록 제외)
+ `Object.defineProperties()`
+ `Object.defineProperty()`
+ `Object.freeze()`
+ `Object.getOwnPropertyDescriptor()`
+ `Object.getOwnPropertyDescriptors()`
+ `Object.getOwnPropertyNames()`
+ `Object.getPrototypeOf()`
+ `Object.isExtensible()`
+ `Object.isFrozen()`
+ `Object.isSealed()`
+ `Object.keys()`
+ `Object.preventExtensions()`
+ `Object.seal()`
객체에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `Object.assign()`
객체에 대해 다음과 같은 ES 8 메서드가 지원됩니다.  
+ `Object.entries()`
+ `Object.values()`
객체에 대해 다음과 같은 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `Object.prototype.hasOwnProperty()`
+ `Object.prototype.isPrototypeOf()`
+ `Object.prototype.propertyIsEnumerable()`
+ `Object.prototype.toString()`
+ `Object.prototype.valueOf()`
객체에 대해 다음과 같은 ES 6 프로토타입 메서드가 지원됩니다.  
+ `Object.prototype.is()`
+ `Object.prototype.setPrototypeOf()`

**문자열**  
문자열에 대해 다음 ES 5.1 메서드가 지원됩니다.  
+ `String.fromCharCode()`
문자열에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `String.fromCodePoint()`
문자열에 대해 다음 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `String.prototype.charAt()`
+ `String.prototype.concat()`
+ `String.prototype.indexOf()`
+ `String.prototype.lastIndexOf()`
+ `String.prototype.match()`
+ `String.prototype.replace()`
+ `String.prototype.search()`
+ `String.prototype.slice()`
+ `String.prototype.split()`
+ `String.prototype.substr()`
+ `String.prototype.substring()`
+ `String.prototype.toLowerCase()`
+ `String.prototype.trim()`
+ `String.prototype.toUpperCase()`
문자열에 대해 다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `String.prototype.codePointAt()`
+ `String.prototype.endsWith()`
+ `String.prototype.includes()`
+ `String.prototype.repeat()`
+ `String.prototype.startsWith()`
문자열에 대해 다음 ES 8 프로토타입 메서드가 지원됩니다.  
+ `String.prototype.padStart()`
+ `String.prototype.padEnd()`
문자열에 대해 다음 ES 9 프로토타입 메서드가 지원됩니다.  
+ `String.prototype.trimStart()`
+ `String.prototype.trimEnd()`
문자열에 대해 다음 ES 12 프로토타입 메서드가 지원됩니다.  
+ `String.prototype.replaceAll()`
**참고**  
`String.prototype.replaceAll()`이 JavaScript 런타임 2.0에 새로 추가되었습니다.

**숫자**  
모든 ES 5.1 숫자가 지원됩니다.  
숫자에 대해 다음 ES 6 속성이 지원됩니다.  
+ `Number.EPSILON`
+ `Number.MAX_SAFE_INTEGER`
+ `Number.MIN_SAFE_INTEGER`
+ `Number.MAX_VALUE`
+ `Number.MIN_VALUE`
+ `Number.NaN`
+ `Number.NEGATIVE_INFINITY`
+ `Number.POSITIVE_INFINITY`
숫자에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `Number.isFinite()`
+ `Number.isInteger()`
+ `Number.isNaN()`
+ `Number.isSafeInteger()`
+ `Number.parseInt()`
+ `Number.parseFloat()`
숫자에 대해 다음 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `Number.prototype.toExponential()`
+ `Number.prototype.toFixed()`
+ `Number.prototype.toPrecision()`
ES 12 숫자 구분자가 지원됩니다.  
ES 12 숫자 구분자가 JavaScript 런타임 2.0에 새로 추가되었습니다.

## 기본 제공 객체
<a name="writing-functions-javascript-features-builtin-objects-20"></a>

ES의 다음 내장 객체가 지원됩니다.

**수학 연산**  
모든 ES 5.1 수학 메서드가 지원됩니다.  
CloudFront 함수 런타임 환경에서 `Math.random()` 구현은 함수가 실행될 때의 타임스탬프와 함께 시드된 OpenBSD `arc4random`을(를) 사용합니다.
다음 ES 6 수학 속성이 지원됩니다.  
+ `Math.E`
+ `Math.LN10`
+ `Math.LN2`
+ `Math.LOG10E`
+ `Math.LOG2E`
+ `Math.PI`
+ `Math.SQRT1_2`
+ `Math.SQRT2`
다음 ES 6 수학 메서드가 지원됩니다.  
+ `Math.abs()`
+ `Math.acos()`
+ `Math.acosh()`
+ `Math.asin()`
+ `Math.asinh()`
+ `Math.atan()`
+ `Math.atan2()`
+ `Math.atanh()`
+ `Math.cbrt()`
+ `Math.ceil()`
+ `Math.clz32()`
+ `Math.cos()`
+ `Math.cosh()`
+ `Math.exp()`
+ `Math.expm1()`
+ `Math.floor()`
+ `Math.fround()`
+ `Math.hypot()`
+ `Math.imul()`
+ `Math.log()`
+ `Math.log1p()`
+ `Math.log2()`
+ `Math.log10()`
+ `Math.max()`
+ `Math.min()`
+ `Math.pow()`
+ `Math.random()`
+ `Math.round()`
+ `Math.sign()`
+ `Math.sinh()`
+ `Math.sin()`
+ `Math.sqrt()`
+ `Math.tan()`
+ `Math.tanh()`
+ `Math.trunc()`

**날짜**  
모든 ES 5.1 `Date` 기능이 지원됩니다.  
보안상의 이유로 단일 함수 실행의 수명 동안 `Date`은(는) 항상 동일한 값(함수의 시작 시간)을 반환합니다. 자세한 내용은 [제한된 기능](functions-javascript-runtime-10.md#writing-functions-javascript-features-restricted-features) 단원을 참조하세요.

**함수**  
다음 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `Function.prototype.apply()`
+ `Function.prototype.bind()`
+ `Function.prototype.call()`
함수 생성자는 지원되지 않습니다.

**정규식**  
모든 ES 5.1 정규 표현식 기능이 지원됩니다. 정규 표현식 언어는 Perl과 호환됩니다.  
다음 ES 5.1 프로토타입 접근자 속성이 지원됩니다.  
+ `RegExp.prototype.global`
+ `RegExp.prototype.ignoreCase`
+ `RegExp.protoype.multiline`
+ `RegExp.protoype.source`
+ `RegExp.prototype.sticky`
+ `RegExp.prototype.flags`
**참고**  
`RegExp.prototype.sticky`, `RegExp.prototype.flags`가 JavaScript 런타임 2.0에 새로 추가되었습니다.
다음 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `RegExp.prototype.exec()`
+ `RegExp.prototype.test()`
+ `RegExp.prototype.toString()`
+ `RegExp.prototype[@@replace]()`
+ `RegExp.prototype[@@split]()`
**참고**  
`RegExp.prototype[@@split]()`이 JavaScript 런타임 2.0에 새로 추가되었습니다.
다음 ES 5.1 인스턴스 속성이 지원됩니다.  
+ `lastIndex`
ES 9 명명된 캡처 그룹이 지원됩니다.

**JSON**  
다음 ES 5.1 메서드가 지원됩니다.  
+ `JSON.parse()`
+ `JSON.stringify()`

**배열**  
배열에 대해 다음 ES 5.1 메서드가 지원됩니다.  
+ `Array.isArray()`
배열에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `Array.of()`
다음 ES 5.1 프로토타입 메서드가 지원됩니다.  
+ `Array.prototype.concat()`
+ `Array.prototype.every()`
+ `Array.prototype.filter()`
+ `Array.prototype.forEach()`
+ `Array.prototype.indexOf()`
+ `Array.prototype.join()`
+ `Array.prototype.lastIndexOf()`
+ `Array.prototype.map()`
+ `Array.prototype.pop()`
+ `Array.prototype.push()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.reverse()`
+ `Array.prototype.shift()`
+ `Array.prototype.slice()`
+ `Array.prototype.some()`
+ `Array.prototype.sort()`
+ `Array.prototype.splice()`
+ `Array.prototype.unshift()`
다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `Array.prototype.copyWithin()`
+ `Array.prototype.fill()`
+ `Array.prototype.find()`
+ `Array.prototype.findIndex()`
다음 ES 7 프로토타입 메서드가 지원됩니다.  
+ `Array.prototype.includes()`

**형식화된 배열**  
다음 ES 6 형식화된 배열 생성자가 지원됩니다.  
+ `Float32Array`
+ `Float64Array`
+ `Int8Array`
+ `Int16Array`
+ `Int32Array`
+ `Uint8Array`
+ `Uint8ClampedArray`
+ `Uint16Array`
+ `Uint32Array`
다음 ES 6 메서드가 지원됩니다.  
+ `TypedArray.from()`
+ `TypedArray.of()`
**참고**  
`TypedArray.from()`, `TypedArray.of()`가 JavaScript 런타임 2.0에 새로 추가되었습니다.
다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `TypedArray.prototype.copyWithin()`
+ `TypedArray.prototype.every()`
+ `TypedArray.prototype.fill()`
+ `TypedArray.prototype.filter()`
+ `TypedArray.prototype.find()`
+ `TypedArray.prototype.findIndex()`
+ `TypedArray.prototype.forEach()`
+ `TypedArray.prototype.includes()`
+ `TypedArray.prototype.indexOf()`
+ `TypedArray.prototype.join()`
+ `TypedArray.prototype.lastIndexOf()`
+ `TypedArray.prototype.map()`
+ `TypedArray.prototype.reduce()`
+ `TypedArray.prototype.reduceRight()`
+ `TypedArray.prototype.reverse()`
+ `TypedArray.prototype.some()`
+ `TypedArray.prototype.set()`
+ `TypedArray.prototype.slice()`
+ `TypedArray.prototype.sort()`
+ `TypedArray.prototype.subarray()`
+ `TypedArray.prototype.toString()`
**참고**  
`TypedArray.prototype.every()`, `TypedArray.prototype.fill()`, `TypedArray.prototype.filter()`, `TypedArray.prototype.find()`, `TypedArray.prototype.findIndex()`, `TypedArray.prototype.forEach()`, `TypedArray.prototype.includes()`, `TypedArray.prototype.indexOf()`, `TypedArray.prototype.join()`, `TypedArray.prototype.lastIndexOf()`, `TypedArray.prototype.map()`, `TypedArray.prototype.reduce()`, `TypedArray.prototype.reduceRight()`, `TypedArray.prototype.reverse()`, `TypedArray.prototype.some()`이 JavaScript 런타임 2.0에 새로 추가되었습니다.

**배열 버퍼**  
ArrayBuffer에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `isView()`
ArrayBuffer에 대해 다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `ArrayBuffer.prototype.slice()`

**Promise**  
프로미스에 대해 다음 ES 6 메서드가 지원됩니다.  
+ `Promise.all()`
+ `Promise.allSettled()`
+ `Promise.any()`
+ `Promise.reject()`
+ `Promise.resolve()`
+ `Promise.race()`
**참고**  
`Promise.all()`, `Promise.allSettled()`, `Promise.any()`, `Promise.race()`가 JavaScript 런타임 2.0에 새로 추가되었습니다.
프로미스에 대해 다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `Promise.prototype.catch()`
+ `Promise.prototype.finally()`
+ `Promise.prototype.then()`

**DataView**  
다음 ES 6 프로토타입 메서드가 지원됩니다.  
+ `DataView.prototype.getFloat32()`
+ `DataView.prototype.getFloat64()`
+ `DataView.prototype.getInt16()`
+ `DataView.prototype.getInt32()`
+ `DataView.prototype.getInt8()`
+ `DataView.prototype.getUint16()`
+ `DataView.prototype.getUint32()`
+ `DataView.prototype.getUint8()`
+ `DataView.prototype.setFloat32()`
+ `DataView.prototype.setFloat64()`
+ `DataView.prototype.setInt16()`
+ `DataView.prototype.setInt32()`
+ `DataView.prototype.setInt8()`
+ `DataView.prototype.setUint16()`
+ `DataView.prototype.setUint32()`
+ `DataView.prototype.setUint8()`
**참고**  
모든 Dataview ES 6 프로토타입 메서드가 JavaScript 런타임 2.0에 새로 추가되었습니다.

**Symbol**  
다음 ES 6 메서드가 지원됩니다.  
+ `Symbol.for()`
+ `Symbol.keyfor()`
**참고**  
모든 Symbol ES 6 메서드가 JavaScript 런타임 2.0에 새로 추가되었습니다.

**텍스트 디코더**  
다음 프로토타입 메서드가 지원됩니다.  
+ `TextDecoder.prototype.decode()`
다음 프로토타입 접근자 속성이 지원됩니다.  
+ `TextDecoder.prototype.encoding`
+ `TextDecoder.prototype.fatal`
+ `TextDecoder.prototype.ignoreBOM`

**텍스트 인코더**  
다음 프로토타입 메서드가 지원됩니다.  
+ `TextEncoder.prototype.encode()`
+ `TextEncoder.prototype.encodeInto()`

## 오류 유형
<a name="writing-functions-javascript-features-error-types-20"></a>

다음과 같은 오류 객체가 지원됩니다.
+ `Error`
+ `EvalError`
+ `InternalError`
+ `RangeError`
+ `ReferenceError`
+ `SyntaxError`
+ `TypeError`
+ `URIError`

## Globals
<a name="writing-functions-javascript-features-globals-20"></a>

`globalThis` 객체가 지원됩니다.

다음 ES 5.1 전역 함수가 지원됩니다.
+ `decodeURI()`
+ `decodeURIComponent()`
+ `encodeURI()`
+ `encodeURIComponent()`
+ `isFinite()`
+ `isNaN()`
+ `parseFloat()`
+ `parseInt()`

다음 ES 6 전역 함수가 지원됩니다.
+ `atob()`
+ `btoa()`
**참고**  
`atob()`, `btoa()`가 JavaScript 런타임 2.0에 새로 추가되었습니다.

다음과 같은 글로벌 제약이 지원됩니다.
+ `NaN`
+ `Infinity`
+ `undefined`
+ `arguments`

## 기본 제공 모듈
<a name="writing-functions-javascript-features-builtin-modules-20"></a>

다음 기본 제공 모듈이 지원됩니다.

**Topics**
+ [

### Buffer
](#writing-functions-javascript-features-builtin-modules-buffer-20)
+ [

### 쿼리 문자열
](#writing-functions-javascript-features-builtin-modules-query-string-20)
+ [

### crypto
](#writing-functions-javascript-features-builtin-modules-crypto-20)

### Buffer
<a name="writing-functions-javascript-features-builtin-modules-buffer-20"></a>

이 모듈은 다음과 같은 메서드를 제공합니다.
+ `Buffer.alloc(size[, fill[, encoding]])`

  `Buffer`를 할당합니다.
  + `size`: 버퍼 크기입니다. 정수를 입력합니다.
  + `fill`: 선택 사항입니다. 문자열, `Buffer`, Uint8Array 또는 정수를 입력합니다. 기본값은 `0`입니다.
  + `encoding`: 선택 사항입니다. `fill`이 문자열인 경우 `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.allocUnsafe(size)`

  초기화되지 않은 `Buffer` 값을 할당합니다.
  + `size`: 정수를 입력합니다.
+ `Buffer.byteLength(value[, encoding])`

  값의 길이를 바이트 단위로 반환합니다.
  + `value`: 문자열, `Buffer`, TypedArray, Dataview 또는 Arraybuffer입니다.
  + `encoding`: 선택 사항입니다. `value`가 문자열인 경우 `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.compare(buffer1, buffer2)`

  두 `Buffer`를 비교하면 배열을 정렬하는 데 도움이 됩니다. 두 값이 같으면 `0`, `buffer1`이 먼저 오면 `-1`, `buffer2`가 먼저 오면 `1`을 반환합니다.
  + `buffer1`: `Buffer`를 입력합니다.
  + `buffer2`: 다른 `Buffer`를 입력합니다.
+ `Buffer.concat(list[, totalLength])`

  여러 개의 `Buffer`를 연결합니다. 없으면 `0`을 반환합니다. `totalLength`까지 반환합니다.
  + `list`: `Buffer` 목록을 입력합니다. 이 항목은 `totalLength` 기준으로 잘려서 표시된다는 점에 유의하세요.
  + `totalLength`: 선택 사항입니다. 부호 없는 정수를 입력합니다. 비어 있는 경우 목록에 있는 `Buffer` 인스턴스의 합계를 사용하세요.
+ `Buffer.from(array)`

  배열에서 `Buffer`를 생성합니다.
  + `array`: `0`에서 `255`까지 바이트 배열을 입력합니다.
+ `Buffer.from(arrayBuffer, byteOffset[, length]))`

  `byteOffset` 오프셋에서 시작하여 `length` 길이를 기준으로 `arrayBuffer`에서 뷰를 생성합니다.
  + `arrayBuffer`: `Buffer` 배열을 입력합니다.
  + `byteOffset`: 정수를 입력합니다.
  + `length`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.from(buffer)`

  `Buffer`의 사본을 생성합니다.
  + `buffer`: `Buffer`를 입력합니다.
+ `Buffer.from(object[, offsetOrEncoding[, length]])`

  객체에서 `Buffer`를 생성합니다. `valueOf()` 값이 객체와 동일하지 않으면 `Buffer.from(object.valueOf(), offsetOrEncoding, length)` 값을 반환합니다.
  + `object`: 객체를 입력합니다.
  + `offsetOrEncoding`: 선택 사항입니다. 정수 또는 인코딩 문자열을 입력합니다.
  + `length`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.from(string[, encoding])`

  문자열에서 `Buffer`를 생성합니다.
  + `string`: 문자열을 입력합니다.
  + `encoding`: 선택 사항입니다. `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.isBuffer(object)`

  `object`가 버퍼인지 확인합니다. `true` 또는 `false`를 반환합니다.
  + `object`: 객체를 입력합니다.
+ `Buffer.isEncoding(encoding)`

  `encoding`이 지원되는지 확인합니다. `true` 또는 `false`를 반환합니다.
  + `encoding`: 선택 사항입니다. `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.

이 모듈은 다음과 같은 버퍼 프로토타입 메서드를 제공합니다.
+ `Buffer.prototype.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]])`

  `Buffer`를 대상과 비교합니다. 두 값이 같으면 `0`, `buffer`이 먼저 오면 `1`, `target`가 먼저 오면 `-1`을 반환합니다.
  + `target`: `Buffer`를 입력합니다.
  + `targetStart`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `targetEnd`: 선택 사항입니다. 정수를 입력합니다. 기본값은 `target` 길이입니다.
  + `sourceStart`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `sourceEnd`: 선택 사항입니다. 정수를 입력합니다. 기본값은 `Buffer` 길이입니다.
+ `Buffer.prototype.copy(target[, targetStart[, sourceStart[, sourceEnd]]])`

  버퍼를 `target`으로 복사합니다.
  + `target`: `Buffer` 또는 `Uint8Array`를 입력합니다.
  + `targetStart`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `sourceStart`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `sourceEnd`: 선택 사항입니다. 정수를 입력합니다. 기본값은 `Buffer` 길이입니다.
+ `Buffer.prototype.equals(otherBuffer)`

  `Buffer`와 `otherBuffer`를 비교합니다. `true` 또는 `false`를 반환합니다.
  + `otherBuffer`: 문자열을 입력합니다.
+ `Buffer.prototype.fill(value[, offset[, end][, encoding])`

  `Buffer`를 `value`로 채웁니다.
  + `value`: 문자열, `Buffer` 또는 정수를 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다.
  + `end`: 선택 사항입니다. 정수를 입력합니다.
  + `encoding`: 선택 사항입니다. `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.prototype.includes(value[, byteOffset][, encoding])`

  `Buffer`에서 `value`를 찾습니다. `true` 또는 `false`를 반환합니다.
  + `value`: 문자열, `Buffer`, `Uint8Array` 또는 정수를 입력합니다.
  + `byteOffset`: 선택 사항입니다. 정수를 입력합니다.
  + `encoding`: 선택 사항입니다. `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.prototype.indexOf(value[, byteOffset][, encoding])`

  `Buffer`에서 첫 번째 `value`를 찾습니다. 값이 발견되면 `index`, 발견되지 않으면 `-1`을 반환합니다.
  + `value`: 문자열, `Buffer`, Unit8Array 또는 0에서 255 사이의 정수를 입력합니다.
  + `byteOffset`: 선택 사항입니다. 정수를 입력합니다.
  + `encoding`: 선택 사항입니다. `value`가 문자열인 경우 `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.prototype.lastIndexOf(value[, byteOffset][, encoding])`

  `Buffer`에서 마지막 `value`를 찾습니다. 값이 발견되면 `index`, 발견되지 않으면 `-1`을 반환합니다.
  + `value`: 문자열, `Buffer`, Unit8Array 또는 0에서 255 사이의 정수를 입력합니다.
  + `byteOffset`: 선택 사항입니다. 정수를 입력합니다.
  + `encoding`: 선택 사항입니다. `value`가 문자열인 경우 `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.prototype.readInt8(offset)`

  `Buffer`의 `offset`에서 `Int8`을 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readIntBE(offset, byteLength)`

  `Buffer`의 `offset`에서 `Int`를 빅 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: 선택 사항입니다. `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.readInt16BE(offset)`

  `Buffer`의 `offset`에서 `Int16`을 빅 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readInt32BE(offset)`

  `Buffer`의 `offset`에서 `Int32`를 빅 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readIntLE(offset, byteLength)`

  `Buffer`의 `offset`에서 `Int`를 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.readInt16LE(offset)`

  `Buffer`의 `offset`에서 `Int16`을 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readInt32LE(offset)`

  `Buffer`의 `offset`에서 `Int32`을 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readUInt8(offset)`

  `Buffer`의 `offset`에서 `UInt8`을 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readUIntBE(offset, byteLength)`

  `Buffer`의 `offset`에서 `UInt`를 빅 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.readUInt16BE(offset)`

  `Buffer`의 `offset`에서 `UInt16`을 빅 엔디안으로 읽습니다.
+ 
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readUInt32BE(offset)`

  `Buffer`의 `offset`에서 `UInt32`를 빅 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readUIntLE(offset, byteLength)`

  `Buffer`의 `offset`에서 `UInt`을 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.readUInt16LE(offset)`

  `Buffer`의 `offset`에서 `UInt16`을 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readUInt32LE(offset)`

  `Buffer`의 `offset`에서 `UInt32`을 리틀 엔디안으로 읽습니다.
  + `offset`: 정수를 입력합니다.
+ `Buffer.prototype.readDoubleBE([offset])`

  `Buffer`의 `offset`에서 64비트 배정도를 빅 엔디안으로 읽습니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.prototype.readDoubleLE([offset])`

  `Buffer`의 `offset`에서 64비트 배정도를 리틀 엔디안으로 읽습니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.prototype.readFloatBE([offset])`

  `Buffer`의 `offset`에서 32비트 부동소수점을 빅 엔디안으로 읽습니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.prototype.readFloatLE([offset])`

  `Buffer`의 `offset`에서 32비트 부동소수점을 리틀 엔디안으로 읽습니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다.
+ `Buffer.prototype.subarray([start[, end]])`

  오프셋되고 새 `start` 및 `end`로 크롭된 `Buffer`의 복사본을 반환합니다.
  + `start`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `end`: 선택 사항입니다. 정수를 입력합니다. 기본값은 버퍼 길이입니다.
+ `Buffer.prototype.swap16()`

  `Buffer` 배열을 16비트 숫자로 구성된 배열로 취급하여 바이트 순서를 바꿉니다. `Buffer` 길이는 2로 나눌 수 있어야 합니다. 그렇지 않으면 오류가 발생합니다.
+ `Buffer.prototype.swap32()`

  `Buffer` 배열을 32비트 숫자로 구성된 배열로 취급하여 바이트 순서를 바꿉니다. `Buffer` 길이는 4로 나눌 수 있어야 합니다. 그렇지 않으면 오류가 발생합니다.
+ `Buffer.prototype.swap64()`

  `Buffer` 배열을 64비트 숫자로 구성된 배열로 취급하여 바이트 순서를 바꿉니다. `Buffer` 길이는 8로 나눌 수 있어야 합니다. 그렇지 않으면 오류가 발생합니다.
+ `Buffer.prototype.toJSON()`

  `Buffer`를 JSON으로 반환합니다.
+ `Buffer.prototype.toString([encoding[, start[, end]]])`

  `start`에서 `end`로, 인코딩된 문자열로 `Buffer`를 변환합니다.
  + `encoding`: 선택 사항입니다. `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
  + `start`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `end`: 선택 사항입니다. 정수를 입력합니다. 기본값은 버퍼 길이입니다.
+ `Buffer.prototype.write(string[, offset[, length]][, encoding])`

  공간이 있는 경우 인코딩된 `string`을 `Buffer`에 쓰고, 공간이 충분하지 않으면 잘라낸 `string`을 씁니다.
  + `string`: 문자열을 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
  + `length`: 선택 사항입니다. 정수를 입력합니다. 기본값은 문자열 길이입니다.
  + `encoding`: 선택 사항입니다. 필요에 따라 `utf8`, `hex`, `base64`, `base64url` 중 하나를 입력합니다. 기본값은 `utf8`입니다.
+ `Buffer.prototype.writeInt8(value, offset, byteLength)`

  `offset`에서 `byteLength`의 `Int8` `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeIntBE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeInt16BE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeInt32BE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeIntLE(offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeInt16LE(offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeInt32LE(offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUInt8(value, offset, byteLength)`

  `offset`에서 `byteLength`의 `UInt8` `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUIntBE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUInt16BE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUInt32BE(value, offset, byteLength)`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUIntLE(value, offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUInt16LE(value, offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeUInt32LE(value, offset, byteLength)`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 정수를 입력합니다.
  + `byteLength`: `1`에서 `6`까지의 정수를 입력합니다.
+ `Buffer.prototype.writeDoubleBE(value, [offset])`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
+ `Buffer.prototype.writeDoubleLE(value, [offset])`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
+ `Buffer.prototype.writeFloatBE(value, [offset])`

  빅 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.
+ `Buffer.prototype.writeFloatLE(value, [offset])`

  리틀 엔디안을 사용하여 `offset`에서 `value`를 `Buffer`에 씁니다.
  + `value`: 정수를 입력합니다.
  + `offset`: 선택 사항입니다. 정수를 입력합니다. 기본값은 0.

다음 인스턴스 메서드가 지원됩니다.
+ `buffer[index]`

  `Buffer`에 `index`의 8진수(바이트)를 가져와 설정합니다.
  + `0`에서 `255`의 숫자를 가져옵니다. 또는 `0`부터 `255`까지의 숫자를 설정할 수도 있습니다.

다음 인스턴스 속성이 지원됩니다.
+ `buffer`

  버퍼의 `ArrayBuffer` 객체를 가져옵니다.
+ `byteOffset`

  버퍼의 `Arraybuffer` 객체에 대한 `byteOffset`을 가져옵니다.
+ `length`

  버퍼 바이트 수를 가져옵니다.

**참고**  
모든 버퍼 모듈 메서드가 JavaScript 런타임 2.0에 새로 추가되었습니다.

### 쿼리 문자열
<a name="writing-functions-javascript-features-builtin-modules-query-string-20"></a>

**참고**  
[CloudFront 함수 이벤트 객체](functions-event-structure.md)는 URL 쿼리 문자열을 자동으로 구문 분석합니다. 즉, 대부분의 경우 이 모듈을 사용할 필요가 없습니다.

쿼리 문자열 모듈(`querystring`)은 URL 쿼리 문자열을 구문 분석하고 서식을 지정하는 메서드를 제공합니다. `require('querystring')`을 사용하여 모듈을 로드할 수 있습니다. 이 모듈은 다음과 같은 방법을 제공합니다.

`querystring.escape(string)`  
지정된 `string`을 URL-인코딩하여 이스케이프된 쿼리 문자열을 반환합니다. 이 방법은 `querystring.stringify()`에서 사용되며 직접 사용해서는 안 됩니다.

`querystring.parse(string[, separator[, equal[, options]]])`  
쿼리 문자열(`string`)을 구문 분석하고 객체를 반환합니다.  
`separator` 파라미터는 쿼리 문자열에서 키와 값 페어를 구분하기 위한 하위 문자열입니다. 기본 설정은 `&`입니다.  
`equal` 파라미터는 쿼리 문자열에서 키와 값을 구분하기 위한 하위 문자열입니다. 기본 설정은 `=`입니다.  
`options` 파라미터는 다음 키를 가진 객체입니다.    
`decodeURIComponent function`  
쿼리 문자열에서 백분율로 인코딩된 문자를 디코딩하는 함수입니다. 기본 설정은 `querystring.unescape()`입니다.  
`maxKeys number`  
구문 분석할 최대 키 수입니다. 기본 설정은 `1000`입니다. `0` 값을 사용하여 키 카운트 제한을 제거합니다.
기본적으로 쿼리 문자열 내의 백분율로 인코딩된 문자는 UTF-8 인코딩을 사용하는 것으로 간주됩니다. 잘못된 UTF-8 시퀀스는 `U+FFFD` 대체 문자로 대체됩니다.  
예를 들어 다음 쿼리 문자열의 경우:  

```
'name=value&abc=xyz&abc=123'
```
`querystring.parse()`의 반환 값:  

```
{
name: 'value',
abc: ['xyz', '123']
}
```
`querystring.decode()`는 `querystring.parse()`의 별칭입니다.

`querystring.stringify(object[, separator[, equal[, options]]])`  
`object`를 직렬화하고 쿼리 문자열을 반환합니다.  
`separator` 파라미터는 쿼리 문자열에서 키와 값 쌍을 구분하기 위한 하위 문자열입니다. 기본 설정은 `&`입니다.  
`equal` 파라미터는 쿼리 문자열에서 키와 값을 구분하기 위한 하위 문자열입니다. 기본 설정은 `=`입니다.  
`options` 파라미터는 다음 키를 가진 객체입니다.    
`encodeURIComponent function`  
URL에 안전하지 않은 문자를 쿼리 문자열에서 백분율 인코딩으로 변환하는 데 사용할 함수입니다. 기본 설정은 `querystring.escape()`입니다.
기본적으로 쿼리 문자열 내에서 백분율 인코딩이 필요한 문자는 UTF-8로 인코딩됩니다. 다른 인코딩을 사용하려면 `encodeURIComponent` 옵션을 지정합니다.  
예를 들어, 다음 코드의 경우:  

```
querystring.stringify({ name: 'value', abc: ['xyz', '123'], anotherName: '' });
```
반환 값:  

```
'name=value&abc=xyz&abc=123&anotherName='
```
`querystring.encode()`는 `querystring.stringify()`의 별칭입니다.

`querystring.unescape(string)`  
지정된 `string`의 URL 백분율로 인코딩된 문자를 디코딩하여 이스케이프되지 않은 쿼리 문자열을 반환합니다. 이 방법은 `querystring.parse()`에서 사용되며 직접 사용해서는 안 됩니다.

### crypto
<a name="writing-functions-javascript-features-builtin-modules-crypto-20"></a>

암호화 모듈(`crypto`)은 표준 해싱 및 HMAC(해시 기반 메시지 인증 코드) 헬퍼를 제공합니다. `require('crypto')`을(를) 사용하여 모듈을 로드할 수 있습니다.

**해싱 메서드**

`crypto.createHash(algorithm)`  
지정된 알고리즘(`md5`, `sha1` 또는 `sha256`)을 사용하여 해시 다이제스트를 생성하는 데 사용할 수 있는 해시 객체를 생성하고 반환합니다.

`hash.update(data)`  
지정된 `data`(으)로 해시 콘텐츠를 업데이트합니다.

`hash.digest([encoding])`  
`hash.update()`을(를) 사용하여 전달된 모든 데이터의 다이제스트를 계산합니다. 인코딩은 `hex`, `base64` 또는 `base64url`일 수 있습니다.

**HMAC 메서드**

`crypto.createHmac(algorithm, secret key)`  
지정된 `algorithm` 및 `secret key`을(를) 사용하는 HMAC 객체를 생성 및 반환합니다. 알고리즘은 `md5`, `sha1` 또는 `sha256`일 수 있습니다.

`hmac.update(data)`  
지정된 `data`(으)로 HMAC 콘텐츠를 업데이트합니다.

`hmac.digest([encoding])`  
`hmac.update()`을(를) 사용하여 전달된 모든 데이터의 다이제스트를 계산합니다. 인코딩은 `hex`, `base64` 또는 `base64url`일 수 있습니다.

## 제한된 기능
<a name="writing-functions-javascript-features-restricted-features-20"></a>

다음 JavaScript 언어 기능은 보안 문제로 인해 지원되지 않거나 제한됩니다.

**동적 코드 평가**  
동적 코드 평가는 지원되지 않습니다. 시도하면 `eval()` 및 `Function` 생성자 모두 오류가 발생합니다. 예를 들어 `const sum = new Function('a', 'b', 'return a + b')`에서 오류가 발생합니다.

**타이머**  
`setTimeout()`, `setImmediate()` 및 `clearTimeout()` 함수는 지원되지 않습니다. 함수 실행 내에서 연기하거나 출력할 프로비전이 없습니다. 함수가 완료되려면 동기적으로 실행되어야 합니다.

**날짜 및 타임스탬프**  
보안상의 이유로 고해상도 타이머에 액세스할 수 없습니다. 현재 시간을 쿼리하는 모든 `Date` 메서드는 단일 함수 실행의 수명 동안 항상 동일한 값을 반환합니다. 반환된 타임 스탬프는 함수가 실행을 시작한 시간입니다. 따라서 함수에서 경과 시간을 측정할 수 없습니다.

**파일 시스템 액세스**  
파일 시스템 액세스가 없습니다. 예를 들어 Node.js에서처럼 파일 시스템 액세스를 위한 `fs` 모듈이 없습니다.

**프로세스 액세스**  
프로세스 액세스가 없습니다. 예를 들어 Node.js와는 달리 정보 액세스를 처리하기 위한 `process` 글로벌 객체가 없습니다.

**환경 변수**  
환경 변수에 액세스할 수 없습니다. 대신 CloudFront KeyValueStore를 사용하여 CloudFront Functions에 대한 키 값 페어의 중앙 집중식 데이터 스토어를 생성할 수 있습니다. CloudFront KeyValueStore를 사용하면 코드 변경 사항을 배포할 필요 없이 구성 데이터를 동적으로 업데이트할 수 있습니다. 자세한 내용은 [Amazon CloudFront KeyValueStore](kvs-with-functions.md) 섹션을 참조하세요.

**네트워크 액세스**  
네트워크 통화에 대한 지원이 없습니다. 예를 들어 XHR, HTTP(S) 및 소켓은 지원되지 않습니다.

# 키 값 저장소를 위한 도우미 메서드
<a name="functions-custom-methods"></a>

**참고**  
CloudFront Functions의 키 값 저장소 헬퍼 메서드 호출은 AWS CloudTrail 데이터 이벤트를 트리거하지 않습니다. 이러한 이벤트는 CloudTrail 이벤트 기록에 로그되지 않습니다. 자세한 내용은 [AWS CloudTrail을 사용하여 Amazon CloudFront API 직접 호출 로깅](logging_using_cloudtrail.md) 섹션을 참조하세요.

이 섹션은 생성한 함수에 [CloudFront 키 값 저장소](kvs-with-functions.md)를 사용하여 키 값을 포함하는 경우에 적용됩니다. CloudFront Functions에는 키 값 저장소에서 값을 읽을 수 있는 세 가지 도우미 메서드를 제공하는 모듈이 있습니다.

함수 코드에서 이 모듈을 사용하려면 [키 값 저장소를 함수와 연결](kvs-with-functions-associate.md)했는지 확인합니다.

그런 다음 함수 코드의 첫 줄에 다음 명령문을 포함시킵니다.

```
import cf from 'cloudfront';
const kvsHandle = cf.kvs();
```



## `get()` 메서드
<a name="functions-custom-methods-get"></a>

이 메서드를 사용하여 지정한 키 이름의 키 값을 반환합니다.

**요청**

```
get("key", options);
```
+ `key`: 값을 가져와야 하는 키의 이름입니다.
+ `options`: 한 가지 옵션으로 `format`이 있습니다. 이 옵션을 사용하면 함수가 데이터를 올바르게 파싱합니다. 가능한 값은 다음과 같습니다.
  + `string`: (기본값) UTF8 인코딩
  + `json` 
  + `bytes`: 원시 바이너리 데이터 버퍼

**요청 예제**

```
const value = await kvsHandle.get("myFunctionKey", { format: "string"});
```

**응답**

응답은 `options`를 사용하여 요청한 형식의 값으로 해석되는 `promise`입니다. 기본적으로 값은 문자열로 반환됩니다.

### 오류 처리
<a name="error-handling-exists-method"></a>

요청된 키가 관련 키 값 저장소에 존재하지 않는 경우 `get()` 메서드는 오류를 반환합니다. 이 사용 사례를 관리하기 위해 코드에 `try` 및 `catch` 블록을 추가할 수 있습니다.

**주의**  
promise 결합자(예: `Promise.all`, `Promise.any`) 및 promise 체인 메서드(예: `then` 및 `catch`)를 사용하려면 많은 함수 메모리 사용량이 필요할 수 있습니다. 함수가 [최대 함수 메모리](cloudfront-limits.md#limits-functions) 할당량을 초과하면 실행에 실패합니다. 이 오류를 방지하려면 `await` 구문을 순차적으로 사용하거나 루프에서 여러 값을 요청하는 것이 좋습니다.  
**예제**  

```
var value1 = await kvs.get('key1');
var value2 = await kvs.get('key2');
```
현재 다음 예제와 같이 promise 결합자를 사용하여 여러 값을 가져오더라도 성능이 향상되지 않습니다.  

```
var values = await Promise.all([kvs.get('key1'), kvs.get('key2'),]);
```

## `exists()` 메서드
<a name="functions-custom-methods-exists"></a>

키가 키 값 저장소에 존재하는지 여부를 지정하려면 이 메서드를 사용합니다.

**요청**

```
exists("key");
```

**요청 예제**

```
const exist = await kvsHandle.exists("myFunctionkey");
```

**응답**

응답은 부울(`true` 또는 `false`)을 반환하는 `promise`입니다. 이 값은 키가 키 값 저장소에 존재하는지 여부를 지정합니다.

## `meta()` 메서드
<a name="functions-custom-methods-meta"></a>

이 메서드를 사용하여 키 값 저장소에 대한 메타데이터를 반환합니다.

**요청**

```
meta();
```

**요청 예제**

```
const meta = await kvsHandle.meta();
```

**응답**

응답은 다음과 같은 속성을 가진 객체로 확인되는 `promise`입니다.
+ `creationDateTime`: 키 값 저장소가 생성된 ISO 8601 형식의 날짜 및 시간입니다.
+ `lastUpdatedDateTime`: 키 값 저장소가 소스에서 마지막으로 동기화된 ISO 8601 형식의 날짜 및 시간입니다. 엣지로의 전파 시간은 값에 포함되지 않습니다.
+ `keyCount`: 소스와의 마지막 동기화 이후 KVS에 있는 키의 총 개수입니다.

**응답 예제**

```
{keyCount:3,creationDateTime:2023-11-30T23:07:55.765Z,lastUpdatedDateTime:2023-12-15T03:57:52.411Z}
```

# 오리진 수정용 헬퍼 메서드
<a name="helper-functions-origin-modification"></a>

이 섹션은 CloudFront Functions 코드 내에서 요청에 사용되는 오리진을 동적으로 업데이트하거나 변경하는 경우에 적용됩니다. *뷰어 요청* CloudFront Functions에서만 오리진을 업데이트할 수 있습니다. CloudFront Functions에는 오리진을 동적으로 업데이트하거나 변경하는 헬퍼 메서드를 제공하는 모듈이 있습니다.

이 모듈을 사용하려면 JavaScript 런타임 2.0을 사용하여 CloudFront Functions을 만들고 함수 코드의 첫 번째 줄에 다음 스테이트먼트를 포함합니다.

```
import cf from 'cloudfront';
```

자세한 내용은 [CloudFront Functions를 위한 JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md) 섹션을 참조하세요.

**참고**  
테스트 API 및 테스트 콘솔 페이지에서는 오리진 수정이 발생했는지 여부를 테스트하지 않습니다. 그러나 테스트는 함수 코드가 오류 없이 실행되도록 합니다.

## CloudFront Functions과 Lambda@Edge 중에서 선택
<a name="origin-modification-considerations"></a>

CloudFront Functions 또는 Lambda@Edge를 사용하여 오리진을 업데이트할 수 있습니다.

CloudFront Functions을 사용하여 오리진을 업데이트할 때 *뷰어 요청* 이벤트 트리거를 사용합니다. 즉, 이 함수가 사용될 때 해당 로직이 모든 요청에서 실행됩니다. Lambda@Edge를 사용하는 경우 오리진 업데이트 기능은 *오리진 요청* 이벤트 트리거에 존재합니다. 즉, 이 로직은 캐시 누락에서만 실행됩니다.

주로 워크로드와 배포에서 CloudFront Functions 및 Lambda@Edge의 기존 사용량에 따라 선택이 달라집니다. 다음 고려 사항을 통해 CloudFront Functions 또는 Lambda@Edge를 사용하여 오리진을 업데이트할지 여부를 결정할 수 있습니다.

CloudFront Functions은 다음과 같은 상황에서 가장 유용합니다.
+ 요청이 동적(즉, 캐싱할 수 없음)이고 항상 오리진으로 이동하는 경우입니다. CloudFront Functions은 더 나은 성능과 더 낮은 전체 비용을 제공합니다.
+ 각 요청에서 실행되는 기존 뷰어 요청 CloudFront Functions이 이미 있는 경우 기존 함수에 오리진 업데이트 로직을 추가할 수 있습니다.

CloudFront Functions을 사용하여 오리진을 업데이트하려면 다음 주제의 헬퍼 메서드를 참조하시기 바랍니다.

Lambda@Edge는 다음과 같은 상황에서 가장 유용합니다.
+ 캐싱 가능성이 높은 콘텐츠가 있으면 Lambda@Edge는 캐시 누락 시에만 실행되고 CloudFront Functions은 모든 요청 시 실행되므로 더 비용 효율적일 수 있습니다.
+ 기존 오리진 요청 Lambda@Edge 함수가 이미 있는 경우 오리진 업데이트 로직을 기존 함수에 추가할 수 있습니다.
+ 오리진 업데이트 로직에서 Amazon DynamoDB 또는 Amazon S3와 같은 서드 파티 데이터 소스에서 데이터를 가져와야 하는 경우입니다.

Lambda@Edge에 대한 자세한 내용은 [Lambda@Edge를 사용하여 엣지에서 사용자 지정](lambda-at-the-edge.md) 섹션을 참조하시기 바랍니다.

## updateRequestOrigin() 메서드
<a name="update-request-origin-helper-function"></a>

`updateRequestOrigin()` 메서드를 사용하여 요청의 오리진 설정을 업데이트합니다. 이 메서드를 사용하여 배포에 이미 정의된 오리진의 기존 오리진 속성을 업데이트하거나 요청에 대한 새 오리진을 정의할 수 있습니다. 이렇게 하려면 변경하려는 속성을 지정합니다.

**중요**  
`updateRequestOrigin()`에서 지정하지 않은 설정은 기존 오리진의 구성에서 *동일한 설정*을 상속합니다.

`updateRequestOrigin()` 메서드에 따라 설정된 오리진은 HTTP 엔드포인트일 수 있으며 CloudFront 배포 내의 기존 오리진일 필요는 없습니다.

**참고**  
오리진 그룹의 일부인 오리진을 업데이트하는 경우 오리진 그룹의 *프라이머리 오리진*만 업데이트됩니다. 보조 오리진은 변경되지 않습니다. 장애 조치 기준과 일치하는 수정된 오리진의 모든 응답 코드는 보조 오리진으로 장애 조치를 트리거합니다.
오리진 유형을 변경하고 OAC를 사용 설정한 경우 `originAccessControlConfig`의 오리진 유형이 새 오리진 유형과 일치하는지 확인합니다.
`updateRequestOrigin()` 메서드를 사용하여 [VPC 오리진](private-content-vpc-origins.md)을 업데이트할 수 없습니다. 요청이 완료되지 않습니다.

**요청**

```
updateRequestOrigin({origin properties})
```

`origin properties`에는 다음 사항이 포함될 수 있습니다.

**domainName(선택 사항)**  
오리진의 도메인 이름입니다. 이를 제공하지 않으면 대신 할당된 오리진의 도메인 이름이 사용됩니다.    
**사용자 지정 오리진의 경우**  
DNS 도메인 이름(예: `www.example.com`)을 지정합니다. 도메인 이름에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. 도메인 이름은 최대 253자일 수 있습니다.  
**S3 오리진의 경우**  
Amazon S3 버킷의 DNS 도메인 이름(예: `amzn-s3-demo-bucket.s3.eu-west-1.amazonaws.com`)을 지정합니다. 이름은 최대 128자여야 하며, 모두 소문자여야 합니다.

**hostHeader(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
오리진에 요청할 때 사용할 호스트 헤더입니다. 제공하지 않으면 domainName 파라미터의 값이 사용됩니다. 호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. 호스트 헤더에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. 호스트 헤더는 최대 253자까지 작성할 수 있습니다.

**originPath(선택 사항)**  
요청이 콘텐츠를 찾아야 하는 오리진의 디렉터리 경로입니다. 경로는 슬래시(/)로 시작해야 하지만 슬래시 하나로 끝나지 않아야 합니다. 예를 들어 `example-path/`로 끝나지 않아야 합니다. 이를 제공하지 않으면 할당된 오리진의 오리진 경로가 사용됩니다.    
**사용자 지정 오리진의 경우**  
경로는 URL 인코딩되어야 하고 최대 255자여야 합니다.

**customHeaders(선택 사항)**  
각 사용자 지정 헤더에 대한 헤더 이름 및 값 페어를 지정하여 요청을 포함한 사용자 지정 헤더를 포함할 수 있습니다. 형식은 이벤트 구조에서 요청 및 응답 헤더의 형식과 다릅니다. 다음의 키/값 쌍 구문을 사용합니다.  

```
{"key1": "value1", "key2": "value2", ...}
```
허용되지 않는 헤더는 추가할 수 없으며 동일한 이름의 헤더가 수신되는 요청 `headers`에 존재할 수 없습니다. 헤더 이름은 함수 코드에서 소문자여야 합니다. CloudFront Functions이 이벤트 객체를 HTTP 요청으로 다시 변환하는 경우 헤더 이름에 있는 각 단어의 첫 글자가 대문자로 표시됩니다. 단어는 하이픈으로 구분됩니다.  
예를 들어 함수 코드가 `example-header-name`이라는 이름의 헤더를 추가하는 경우, CloudFront는 이 헤더를 HTTP 요청에서 `Example-Header-Name`으로 변환합니다. 자세한 내용은 [CloudFront에서 오리진 요청에 추가할 수 없는 사용자 지정 헤더](add-origin-custom-headers.md#add-origin-custom-headers-denylist) 및 [엣지 함수에 대한 제한 사항](edge-functions-restrictions.md)(을)를 참조하세요.  
이를 제공하지 않으면 할당된 오리진의 사용자 지정 헤더가 사용됩니다.

**connectionAttempts(선택 사항)**  
CloudFront가 오리진에 연결을 시도하는 횟수입니다. 최솟값은 1이고, 최댓값은 3입니다. 이를 제공하지 않으면 할당된 오리진을 통해 연결 시도가 사용됩니다.

**originShield(선택 사항)**  
이렇게 하면 CloudFront Origin Shield가 사용 설정되거나 업데이트됩니다. Origin Shield를 사용하면 오리진의 부하를 줄일 수 있습니다. 자세한 내용은 [Amazon CloudFront Origin Shield 사용](origin-shield.md) 섹션을 참조하세요. 이를 제공하지 않으면 할당된 오리진을 통해 Origin Shield 설정이 사용됩니다.    
**enabled(필수)**  
Origin Shield를 사용 또는 사용 해제하는 부울 표현식입니다. `true` 또는 `false` 값을 허용합니다.  
**region(사용 설정된 경우 필수)**  
Origin Shield의 AWS 리전입니다. 오리진에 대한 지연 시간이 가장 낮은 AWS 리전을 지정합니다. 리전 이름이 아닌 리전 코드를 사용합니다. 예를 들어 `us-east-2`를 사용하여 미국 동부(오하이오) 리전을 지정합니다.  
CloudFront Origin Shield를 사용하는 경우 이에 대한 AWS 리전을 지정해야 합니다. 사용 가능한 AWS 리전 목록과 오리진에 가장 적합한 리전을 선택하는 데 도움이 되는 목록은 [Origin Shield의 AWS 리전 선택](origin-shield.md#choose-origin-shield-region) 섹션을 참조하시기 바랍니다.

**originAccessControlConfig(선택 사항)**  
해당 오리진에 대한 원본 액세스 제어(OAC)의 고유한 식별자입니다. 이는 오리진이 Amazon S3, Lambda 함수 URL, MediaStore, MediaPackage V2 등 CloudFront OAC를 지원하는 경우에만 사용됩니다. 이를 제공하지 않으면 할당된 오리진의 OAC 설정이 사용됩니다.  
이는 레거시 오리진 액세스 ID(OAI)를 지원하지 않습니다. 자세한 내용은 [AWS 오리진에 대한 액세스 제한](private-content-restricting-access-to-origin.md) 섹션을 참조하세요.    
**enabled(필수)**  
OAC를 사용 또는 사용 해제하는 부울 표현식입니다. `true` 또는 `false` 값을 허용합니다.  
**signingBehavior(사용 설정된 경우 필수)**  
CloudFront가 서명(인증 정보 추가)하는 요청을 지정합니다. 대부분의 사용 사례에서 `always`를 지정합니다.. 자세한 내용은 [오리진 액세스 제어를 위한 고급 설정](private-content-restricting-access-to-s3.md#oac-advanced-settings-s3) 섹션을 참조하세요.  
이 필드는 다음 값 중 하나를 가질 수 있습니다.  
+ `always` - CloudFront가 모든 오리진 요청을 서명하고, 최종 사용자 요청으로부터 `Authorization` 헤더를 덮어씁니다(있는 경우).
+ `never` - CloudFront가 오리진 요청을 서명하지 않습니다. 이 값은 오리진에 대한 오리진 액세스 제어를 끕니다.
+ `no-override` - 뷰어 요청에 `Authorization` 헤더가 포함되지 않은 경우 CloudFront가 오리진 요청을 서명합니다. 뷰어 요청에 `Authorization` 헤더가 포함된 경우 CloudFront가 오리진 요청에 서명하지 않고 최종 사용자 요청의 `Authorization` 헤더와 함께 전달합니다.
**주의**  
뷰어 요청에서 `Authorization` 헤더를 전달하려면 이 오리진 액세스 제어와 연결된 오리진을 사용하는 모든 캐시 동작에 대한 해당 헤더를 오리진 요청 정책에 추가해야 합니다. 자세한 내용은 [정책을 통한 오리진 요청 제어](controlling-origin-requests.md) 섹션을 참조하세요.  
**signingProtocol(사용 설정된 경우 필수)**  
CloudFront가 요청을 서명(인증)하는 방법을 결정하는 OAC의 서명 프로토콜입니다. 유일한 유효 값은 `sigv4`입니다.  
**originType(사용 설정된 경우 필수)**  
이 OAC의 오리진 유형입니다. 유효한 값에는 `s3`, `mediapackagev2`, `mediastore` 및 `lambda` 등이 있습니다.

**timeouts(선택 사항)**  
CloudFront가 오리진이 응답하거나 데이터를 전송할 때까지 대기해야 하는 기간에 대해 지정할 수 있는 제한 시간입니다. 이를 제공하지 않으면 할당된 오리진의 제한 시간 설정이 사용됩니다.  
달리 명시되지 않은 한, 이러한 제한 시간은 사용자 지정 오리진과 Amazon S3 오리진을 모두 지원합니다.  
**readTimeout(선택 사항)**  
`readTimeout`은 다음 두 값 모두에 적용됩니다.  
+ CloudFront가 오리진에 요청을 전달한 후 응답을 기다리는 시간(초).
+ CloudFront가 오리진으로부터 응답 패킷을 수신한 후 다음 패킷을 수신할 때까지 대기하는 시간(초).
최소 제한 시간은 1초이고, 최대 제한 시간은 120초입니다. 자세한 내용은 [응답 제한 시간](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout) 섹션을 참조하세요.  
**responseCompletionTimeout(선택 사항)**  
CloudFront에서 오리진으로의 요청이 열려 있고 응답을 기다릴 수 있는 시간(초). 이 시간까지 오리진에서 완전한 응답을 받지 못하면 CloudFront는 연결을 종료합니다.  
`responseCompletionTimeout` 값은 `readTimeout` 값과 같거나 이보다 커야 합니다. 자세한 내용은 [응답 완료 제한 시간](DownloadDistValuesOrigin.md#response-completion-timeout) 섹션을 참조하세요.  
**keepAliveTimeout(선택 사항)**  
이 제한 시간은 Amazon S3 오리진이 아닌 사용자 지정 오리진에만 적용됩니다. (S3 오리진 구성은 이러한 설정을 무시합니다.)   
`keepAliveTimeout`은 응답의 마지막 패킷을 수신한 후 CloudFront가 오리진에 대한 연결을 유지하려고 시도하는 시간을 지정합니다. 최소 제한 시간은 1초이고, 최대 제한 시간은 120초입니다. 자세한 내용은 [연결 유지 제한 시간(사용자 지정 및 VPC 오리진만 해당)](DownloadDistValuesOrigin.md#DownloadDistValuesOriginKeepaliveTimeout) 섹션을 참조하세요.  
**connectionTimeout(선택 사항)**  
오리진에 대한 연결을 설정하려고 할 때 CloudFront가 대기하는 시간(초)입니다. 최소 제한 시간은 1초이고, 최대 제한 시간은 10초입니다. 자세한 내용은 [연결 제한 시간](DownloadDistValuesOrigin.md#origin-connection-timeout) 섹션을 참조하세요.

**customOriginConfig(선택 사항)**  
`customOriginConfig`를 사용하여 Amazon S3 버킷이 *아닌* 오리진에 대한 연결 설정을 지정합니다. 한 가지 예외는 다음과 같습니다. S3 버킷이 고정 웹 사이트 호스팅으로 구성된 경우 이러한 설정을 지정할 수 있습니다. (다른 유형의 S3 버킷 구성은 이러한 설정을 무시합니다.) `customOriginConfig`가 제공되지 않으면 할당된 오리진의 설정이 사용됩니다.    
**port(필수)**  
CloudFront가 오리진에 연결하는 데 사용하는 HTTP 포트입니다. 오리진에서 수신 대기하는 HTTP 포트를 지정하십시오.  
**protocol(필수)**  
CloudFront가 오리진에 연결하는 데 사용하는 프로토콜(HTTP 또는 HTTPS)을 지정합니다. 유효한 값은 다음과 같습니다.  
+ `http` - CloudFront는 항상 HTTP를 사용하여 오리진에 연결합니다.
+ `https` - CloudFront는 항상 HTTPS를 사용하여 오리진에 연결합니다.  
**sslProtocols(필수)**  
HTTPS를 통해 오리진에 연결할 때 CloudFront에서 사용하는 최소 SSL/TLS 프로토콜을 지정하는 목록입니다. 유효한 값에는 `SSLv3`, `TLSv1`, `TLSv1.1` 및 `TLSv1.2` 등이 있습니다. 자세한 내용은 [최소 오리진 SSL 프로토콜](DownloadDistValuesOrigin.md#DownloadDistValuesOriginSSLProtocols) 섹션을 참조하세요.  
**ipAddressType(선택 사항)**  
CloudFront가 오리진에 연결하는 데 사용하는 IP 주소 유형을 지정합니다. 유효값에는 `ipv4`, `ipv6` 및 `dualstack`이 있습니다. `ipAddressType` 변경은 `domainName` 속성도 변경 중인 경우에만 지원됩니다.

**sni(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
서버 이름 표시(SNI)는 Transport Layer Security(TLS) 프로토콜의 확장으로, 클라이언트가 TLS 핸드셰이크 프로세스를 시작할 때 연결을 시도하는 호스트 이름을 나타냅니다. 이 값은 오리진 서버의 TLS 인증서에 있는 일반 이름과 일치해야 합니다. 그렇지 않으면 오리진 서버에서 오류가 발생할 수 있습니다.  
제공하지 않으면 `hostHeader` 파라미터의 값이 사용됩니다. 호스트 헤더가 제공되지 않으면 `domainName` 파라미터의 값이 사용됩니다.  
호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. SNI에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. SNI는 최대 253자까지 작성할 수 있습니다.

**allowedCertificateNames(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
CloudFront에서 오리진 서버와의 TLS 핸드셰이크 중에 오리진 서버 TLS 인증서와 일치하는 도메인의 유효성을 검사하는 데 사용할 유효한 인증서 이름 목록을 포함할 수 있습니다. 이 필드에는 유효한 도메인 이름 배열이 필요하며 `*.example.com`과 같은 와일드카드 도메인이 포함될 수 있습니다.  
허용되는 인증서 이름은 최대 20개까지 지정할 수 있습니다. 각 인증서의 이름은 최대 64자까지 가능합니다.

**Example - Amazon S3 요청 오리진 업데이트**  
다음 예제에서는 뷰어 요청의 오리진을 S3 버킷으로 변경하고 OAC를 사용 설정하며 오리진으로 전송된 사용자 지정 헤더를 재설정합니다.  

```
cf.updateRequestOrigin({
    "domainName" : "amzn-s3-demo-bucket-in-us-east-1.s3.us-east-1.amazonaws.com",
    "originAccessControlConfig": {
        "enabled": true,
        "signingBehavior": "always",
        "signingProtocol": "sigv4",
        "originType": "s3"
    },
    // Empty object resets any header configured on the assigned origin
    "customHeaders": {}
});
```

**Example - Application Load Balancer 요청 오리진 업데이트**  
다음 예제에서는 뷰어 요청의 오리진을 Application Load Balancer 오리진으로 변경하고 사용자 지정 헤더와 제한 시간을 설정합니다.  

```
cf.updateRequestOrigin({
    "domainName" : "example-1234567890.us-east-1.elb.amazonaws.com",
    "timeouts": {
        "readTimeout": 30,
        "connectionTimeout": 5
    },
    "customHeaders": {
        "x-stage": "production",
        "x-region": "us-east-1"
    }
});
```

**Example - Origin Shield가 사용 설정된 오리진으로 업데이트**  
다음 예제에서는 배포의 오리진에 Origin Shield가 사용 설정되어 있습니다. 함수 코드는 오리진에 사용되는 도메인 이름만 업데이트하고 다른 모든 선택 사항 파라미터를 생략합니다. 이 경우 Origin Shield 파라미터가 업데이트되지 않았으므로 Origin Shield는 수정된 오리진 도메인 이름과 함께 계속 사용됩니다.  

```
cf.updateRequestOrigin({
    "domainName" : "www.example.com"
});
```

**Example - 호스트 헤더, SNI 및 허용된 인증서 이름 업데이트**  
대부분의 사용 사례에서는 오리진으로 이동하는 요청에 이러한 유형의 수정을 사용할 필요가 없습니다. 이러한 값 변경의 영향을 이해하지 못한다면 이러한 파라미터를 사용해서는 안 됩니다.
다음 예시에서는 요청에 대한 도메인 이름, 호스트 헤더, SNI 및 허용된 인증서를 오리진으로 변경합니다.  

```
cf.updateRequestOrigin({ 
    "domainName": "www.example.com", 
    "hostHeader": "test.example.com", 
    "sni": "test.example.net", 
    "allowedCertificateNames": ["*.example.com", "*.example.net"],
});
```

## selectRequestOriginById() 메서드
<a name="select-request-origin-id-helper-function"></a>

`selectRequestOriginById()`를 사용해 배포에 이미 구성된 다른 오리진을 선택하여 기존 오리진을 업데이트합니다. 이 메서드는 업데이트된 오리진에서 정의한 것과 동일한 설정을 모두 사용합니다.

이 메서드는 함수를 실행할 때 사용된 것과 동일한 배포에 이미 정의된 오리진만 허용합니다. 오리진은 오리진을 설정할 때 정의한 오리진 이름인 오리진 ID로 참조됩니다.

배포에 VPC 오리진이 구성된 경우 이 메서드를 사용하여 오리진을 VPC 오리진으로 업데이트할 수 있습니다. 자세한 내용은 [VPC 오리진으로 액세스 제한](private-content-vpc-origins.md) 섹션을 참조하세요.

**참고**  
`selectRequestOriginById()` 함수는 상호 TLS(오리진)가 활성화된 오리진을 선택할 수 없습니다. 이 함수를 사용하여 상호 TLS(오리진)가 활성화된 오리진을 선택하려고 하면 검증 오류가 발생합니다.
사용 사례에 따라 상호 TLS(오리진)를 사용한 동적 오리진 선택이 필요한 경우, 모든 대상 오리진이 동일한 클라이언트 인증서를 사용하도록 `updateRequestOrigin()`을 대신 사용하세요.

**요청**

```
cf.selectRequestOriginById(origin_id, {origin_overrides})
```

이전 예시에서 `origin_id`는 함수를 실행하는 배포에서 오리진의 오리진 이름을 가리키는 문자열입니다. `origin_overrides `파라미터에는 다음이 포함될 수 있습니다.

**hostHeader(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
오리진에 요청할 때 사용할 호스트 헤더입니다. 제공하지 않으면 `domainName` 파라미터의 값이 사용됩니다.  
호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. 호스트 헤더에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. 호스트 헤더는 최대 253자까지 작성할 수 있습니다.

**sni(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
서버 이름 표시(SNI)는 Transport Layer Security(TLS) 프로토콜의 확장으로, 클라이언트가 TLS 핸드셰이크 프로세스를 시작할 때 연결을 시도하는 호스트 이름을 나타냅니다. 이 값은 오리진 서버의 TLS 인증서에 있는 일반 이름과 일치해야 합니다. 그렇지 않으면 오리진 서버에서 오류가 발생할 수 있습니다.  
제공하지 않으면 `hostHeader` 파라미터의 값이 사용됩니다. 호스트 헤더가 제공되지 않으면 `domainName` 파라미터의 값이 사용됩니다.  
호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. SNI에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. SNI는 최대 253자까지 작성할 수 있습니다.

**allowedCertificateNames(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
CloudFront에서 오리진 서버와의 TLS 핸드셰이크 중에 오리진 서버 TLS 인증서와 일치하는 도메인의 유효성을 검사하는 데 사용할 유효한 인증서 이름 목록을 포함할 수 있습니다. 이 필드에는 유효한 도메인 이름 배열이 필요하며 `*.example.com`과 같은 와일드카드 도메인이 포함될 수 있습니다.  
허용되는 인증서 이름은 최대 20개까지 지정할 수 있습니다. 각 인증서의 이름은 최대 64자까지 가능합니다.

**요청**

```
selectRequestOriginById(origin_id)
```

앞의 예시에서 `origin_id`는 함수를 실행하는 배포에서 오리진의 오리진 이름을 가리키는 문자열입니다.

**Example - Amazon S3 요청 오리진 선택**  
다음 예시에서는 배포와 연결된 오리진 목록에서 `amzn-s3-demo-bucket-in-us-east-1`라는 오리진을 선택하고 `amzn-s3-demo-bucket-in-us-east-1` 오리진의 구성 설정을 요청에 적용합니다.  

```
cf.selectRequestOriginById("amzn-s3-demo-bucket-in-us-east-1");
```

**Example - Application Load Balancer 요청 오리진 선택**  
다음 예시에서는 배포와 연결된 오리진 목록에서 `myALB-prod`라는 Application Load Balancer 오리진을 선택하고 `myALB-prod`의 구성 설정을 요청에 적용합니다.  

```
cf.selectRequestOriginById("myALB-prod");
```

**Example - Application Load Balancer 요청 오리진을 선택하고 호스트 헤더를 재정의합니다.**  
이전 예시와 같이 다음 예시에서는 배포와 연결된 오리진 목록에서 `myALB-prod`라는 Application Load Balancer 오리진을 선택하고 `myALB-prod`의 구성 설정을 요청에 적용합니다. 그러나 이 예제에서는 `origin_overrides`를 사용하여 호스트 헤더 값을 재정의합니다.  

```
cf.overrideRequestOrigin("myALB-prod",{ 
        "hostHeader" : "test.example.com"
});
```

## createRequestOriginGroup() 메서드
<a name="create-request-origin-group-helper-function"></a>

`createRequestOriginGroup()`를 사용하여 고가용성이 필요한 시나리오에서 장애 조치용 [오리진 그룹](high_availability_origin_failover.md#concept_origin_groups.creating)으로 사용할 두 개의 오리진을 정의합니다.

오리진 그룹에는 두 개의 오리진(프라이머리 및 보조)과 사용자가 지정하는 장애 조치 기준이 포함됩니다. CloudFront에서 오리진 장애 조치를 지원할 오리진 그룹을 생성합니다. 이 메서드를 사용하여 오리진 그룹을 생성하거나 업데이트할 때 단일 오리진 대신 오리진 그룹을 지정할 수 있습니다. CloudFront는 장애 조치 기준을 사용하여 프라이머리 오리진에서 보조 오리진으로 장애 조치를 수행합니다.

배포에 VPC 오리진이 구성된 경우 이 메서드를 통해 VPC 오리진을 사용하여 오리진 그룹을 생성할 수 있습니다. 자세한 내용은 [VPC 오리진으로 액세스 제한](private-content-vpc-origins.md) 섹션을 참조하세요.

**참고**  
`createRequestOriginGroup()` 함수는 상호 TLS(오리진)가 활성화된 오리진을 포함하는 오리진 그룹 생성을 지원하지 않습니다. 상호 TLS(오리진) 오리진이 있는 오리진 그룹은 CloudFront Functions를 통해 동적으로 생성할 수 없습니다.
상호 TLS(오리진)를 사용한 오리진 장애 조치 기능이 필요한 경우 함수에서 동적으로 생성하는 대신 CloudFront 배포 설정에서 오리진 그룹을 직접 구성하세요.

### 요청
<a name="create-origin-group-request"></a>

```
createRequestOriginGroup({origin_group_properties})
```

앞의 예시에서 `origin_group_properties`에는 다음이 포함될 수 있습니다.

**originIds(필수)**  
`origin_ids` 배열이며, 여기서 `origin_id`는 함수를 실행하는 배포에서 오리진의 오리진 이름을 가리키는 문자열입니다. 배열의 일부로 두 개의 오리진을 제공해야 합니다. 목록의 첫 번째 오리진은 프라이머리 오리진이고 두 번째 오리진은 장애 조치를 위한 보조 오리진 역할을 합니다.

**originOverrides(선택 사항)**  
 `{origin_overrides}` 파라미터를 사용하여 몇 가지 고급 설정을 덮어쓸 수 있습니다. `origin overrides`에는 다음 사항이 포함될 수 있습니다.    
**hostHeader(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
오리진에 요청할 때 사용할 호스트 헤더입니다. 제공하지 않으면 `domainName` 파라미터의 값이 사용됩니다.  
호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. 호스트 헤더에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. 호스트 헤더는 최대 253자까지 작성할 수 있습니다.  
**sni(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
서버 이름 표시(SNI)는 클라이언트가 TLS 핸드셰이크 프로세스를 시작할 때 연결을 시도하는 호스트 이름을 나타내는 Transport Layer Security(TLS) 프로토콜의 확장입니다. 이 값은 오리진 서버의 TLS 인증서에 있는 일반 이름과 일치해야 합니다. 그렇지 않으면 오리진 서버에서 오류가 발생할 수 있습니다.  
제공하지 않으면 `hostHeader` 파라미터의 값이 사용됩니다. 호스트 헤더가 제공되지 않으면 `domainName` 파라미터의 값이 사용됩니다.  
호스트 헤더 또는 도메인 이름 파라미터가 제공되지 않은 경우 할당된 오리진의 도메인 이름이 사용되고, 오리진으로 전달(FTO) 정책에 호스트가 포함된 경우 수신 요청의 호스트 헤더가 사용됩니다. SNI에는 콜론(`:`)이 포함될 수 없으며 IP 주소가 될 수 없습니다. SNI는 최대 253자까지 작성할 수 있습니다.  
**allowedCertificateNames(선택 사항, S3가 아닌 사용자 지정 오리진의 경우)**  
CloudFront에서 오리진 서버와의 TLS 핸드셰이크 중에 오리진 서버 TLS 인증서와 일치하는 도메인의 유효성을 검사하는 데 사용할 유효한 인증서 이름 목록을 포함할 수 있습니다. 이 필드에는 유효한 도메인 이름 배열이 필요하며 `*.example.com`과 같은 와일드카드 도메인이 포함될 수 있습니다.  
허용되는 인증서 이름은 최대 20개까지 지정할 수 있습니다. 각 인증서의 이름은 최대 64자까지 가능합니다.

**selectionCriteria(선택 사항)**  
`default` 오리진 장애 조치 기준을 사용할지 아니면 `media-quality-score` 기반 장애 조치 로직을 사용할지 선택합니다. 유효한 값은 다음과 같습니다.  
+ `default`는 `failoverCriteria`에 지정된 상태 코드를 기반으로 장애 조치 기준을 사용합니다. 함수에서 `selectionCriteria`를 설정하지 않으면 `default`가 사용됩니다.
+ `media-quality-score`는 미디어 인식 라우팅 기능을 사용할 때 사용됩니다.

**failoverCriteria(필수)**  
프라이머리 오리진에서 반환될 때 CloudFront가 보조 오리진으로 장애 조치하도록 트리거하는 상태 코드 배열입니다. 기존 오리진 그룹을 덮어쓰면 이 배열은 오리진 그룹의 원래 구성에 설정된 모든 장애 조치 상태 코드를 덮어씁니다.  
`media-quality-score` `selectionCriteria`를 사용하는 경우 CloudFront는 미디어 품질 점수를 기반으로 요청을 라우팅하려고 시도합니다. 선택한 오리진이 이 배열에 설정된 오류 코드를 반환하면 CloudFront는 다른 오리진으로 장애 조치를 수행합니다.

**Example - 요청 오리진 그룹 생성**  
다음 예시에서는 오리진 ID를 사용하여 요청에 대한 오리진 그룹을 생성합니다. 이러한 오리진 ID는 이 함수를 실행하는 데 사용되는 배포의 오리진 그룹 구성에서 가져옵니다.  
선택적으로 `originOverrides`를 사용하여 `sni`, `hostHeader` 및 `allowedCertificateNames`에 대한 오리진 그룹 구성을 재정의할 수 있습니다.  

```
import cf from 'cloudfront';

function handler(event) {
    cf.createRequestOriginGroup({
        "originIds": [
            {
                "originId": "origin-1",
                "originOverrides": {
                    "hostHeader": "hostHeader.example.com",
                    "sni": "sni.example.com",
                    "allowedCertificateNames": ["cert1.example.com", "cert2.example.com", "cert3.example.com"]
                }
            },
            {
                "originId": "origin-2",
                "originOverrides": {
                    "hostHeader": "hostHeader2.example.com",
                    "sni": "sni2.example.com",
                    "allowedCertificateNames": ["cert4.example.com", "cert5.example.com"]
                }
            }
        ],
        "failoverCriteria": {
            "statusCodes": [500]
        }
    });
    
    event.request.headers['x-hookx'] = { value: 'origin-overrides' };
    return event.request;
}
```

# CloudFront SaaS Manager 속성에 대한 헬퍼 메서드
<a name="saas-specific-logic-function-code"></a>

CloudFront SaaS Manager에서 다음 헬퍼 함수를 사용하여 직접 만든 함수에서 다중 테넌트 배포의 값을 검색합니다. 이 페이지의 예제를 사용하려면 먼저 JavaScript 런타임 2.0을 사용하여 CloudFront 함수를 만들어야 합니다. 자세한 설명은 [CloudFront Functions를 위한 JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md) 섹션을 참조하세요.

**Topics**
+ [

## 연결 그룹
](#connection-groups-helper-function)
+ [

## 배포 테넌트
](#distribution-tenants-helper-functions)

## 연결 그룹
<a name="connection-groups-helper-function"></a>

배포 테넌트와 연결된 연결 그룹에는 도메인 이름이 있습니다.

이 값을 가져오려면 이벤트 객체의 `context` 하위 객체에서 `endpoint` 필드를 사용합니다.

**요청**

```
const value = event.context.endpoint;
```

**응답**

응답은 연결 그룹의 도메인 이름이 포함된 `string`(예: d111111abcdef8.cloudfront.net)입니다. `endpoint` 필드는 연결된 연결 그룹이 있는 다중 테넌트 배포에 대해 함수가 호출되는 경우에만 나타납니다. 자세한 내용은 [컨텍스트 객체](functions-event-structure.md#functions-event-structure-context) 섹션을 참조하세요.

## 배포 테넌트
<a name="distribution-tenants-helper-functions"></a>

CloudFront Functions에는 특정 배포 테넌트 값에 대한 액세스를 제공하는 모듈이 있습니다.

이 모듈을 사용하려면 다음 함수 코드의 첫 줄에 다음 스테이트먼트를 포함합니다.

```
import cf from 'cloudfront';
```

다음 예제는 `handler` 함수에서만 직접 또는 중첩 호출 함수를 통해 사용할 수 있습니다.

### `distributionTenant.id` 필드
<a name="distribution-tenants-field"></a>

이 필드를 사용하여 배포 테넌트 ID의 값을 가져옵니다.

**요청**

```
const value = cf.distributionTenant.id;
```

**응답**

응답은 배포 테넌트 ID를 포함하는 `string`(예: `dt_1a2b3c4d5e6f7`)입니다.

**오류 처리**.

함수가 표준 배포에서 호출되는 경우 `distributionTenant.id` 필드를 지정하면 `distributionTenant module is not available` 유형 오류가 반환됩니다. 이 사용 사례를 처리하기 위해 코드에 `try` 및 `catch` 블록을 추가할 수 있습니다.

### `distributionTenant.parameters.get()` 메서드
<a name="distribution-tenant-parameters-get-method"></a>

이 메서드를 사용하여 지정한 배포 테넌트 파라미터 이름의 값을 반환합니다.

```
distributionTenant.parameters.get("key");
```

`key`: 값을 가져오려는 배포 테넌트 파라미터 이름입니다.

**요청**

```
const value = distributionTenant.parameters.get("key");
```

**응답**

응답은 배포 테넌트 파라미터의 값을 포함하는 `string`입니다. 예를 들어 키 이름이 `TenantPath`인 경우 이 파라미터의 값은 `tenant1`일 수 있습니다.

**오류 처리**.

다음 오류가 표시될 수 있습니다.
+ 함수가 표준 배포에서 호출되는 경우 `distributionTenant.parameters.get()` 메서드는 `distributionTenant module is not available` 유형 오류를 반환합니다.
+ 지정한 배포 테넌트 파라미터가 존재하지 않으면 `DistributionTenantParameterKeyNotFound` 오류가 반환됩니다.

이 사용 사례를 관리하기 위해 코드에 `try` 및 `catch` 블록을 추가할 수 있습니다.

# async 및 await 사용
<a name="async-await-syntax"></a>

CloudFront Functions JavaScript 런타임 함수 2.0은 `Promise` 객체를 처리하기 위한 `async` 및 `await` 구문을 제공합니다. 프로미스는 `async`로 표시된 함수의 `await` 키워드를 통해 액세스할 수 있는 지연된 결과를 나타냅니다. 다양한 새 WebCrypto 함수가 프로미스를 사용합니다.

`Promise` 객체에 대한 자세한 내용은 [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)를 참조하세요.

**참고**  
다음 코드 샘플에는 JavaScript 런타임 2.0을 사용해야 합니다.  
`await`는 `async` 함수 내에서만 사용할 수 있습니다. `async` 인수 및 종료는 지원되지 않습니다.

```
async function answer() {
    return 42;
}

// Note: async, await can be used only inside an async function. async arguments and closures are not supported.

async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

다음 예제 JavaScript 코드는 `then` 체인 메서드로 프로미스를 보는 방법을 보여줍니다. `catch`를 사용하여 오류를 확인할 수 있습니다.

**주의**  
promise 결합자(예: `Promise.all`, `Promise.any`) 및 promise 체인 메서드(예: `then` 및 `catch`)를 사용하려면 많은 함수 메모리 사용량이 필요할 수 있습니다. 함수가 [최대 함수 메모리](cloudfront-limits.md#limits-functions) 할당량을 초과하면 실행에 실패합니다. 이 오류를 방지하도록 `promise` 메서드 대신 `await` 구문을 사용하는 것이 좋습니다.

```
async function answer() {
    return 42;
}

async function squared_answer() {
   return answer().then(value => value * value)
} 
// Note: async, await can be used only inside an async function. async arguments and closures are not supported.
async function handler(event) {
    // var answer_value = answer(); // returns Promise, not a 42 value
    let answer_value = await squared_answer(); // resolves Promise, 42
    console.log("Answer"+answer_value);
    event.request.headers['answer'] = { value : ""+answer_value };
    return event.request;
}
```

# CloudFront Functions에 대한 CWT 지원
<a name="cwt-support-cloudfront-functions"></a>

이 섹션에서는 CloudFront 엣지 로케이션에서 보안 토큰 기반 인증 및 권한 부여를 활성화하는 CloudFront Functions의 CBOR 웹 토큰(CWT) 지원에 대한 세부 정보를 제공합니다. 이 지원은 CloudFront Functions에서 액세스할 수 있는 모듈로 제공됩니다.

이 모듈을 사용하려면 JavaScript 런타임 2.0을 사용하여 CloudFront Functions을 만들고 함수 코드의 첫 번째 줄에 다음 스테이트먼트를 포함합니다.

```
import cf from 'cloudfront';
```

이 모듈과 연결된 메서드는 다음을 통해 액세스할 수 있습니다(여기서 \$1는 모듈에 있는 다양한 함수를 나타내는 와일드카드).

```
cf.cwt.*
```

자세한 내용은 [CloudFront Functions를 위한 JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md) 섹션을 참조하세요.

현재 모듈은 최대 토큰 크기에 대해 한도가 1KB인 HS256(HMAC-SHA256) 알고리즘을 사용하는 MAC0 구조만 지원합니다.

## 토큰 구조
<a name="token-structure"></a>

이 섹션에서는 CWT 모듈에서 예상되는 토큰 구조를 다룹니다. 모듈은 토큰에 태그를 올바르게 지정하고 식별할 수 있어야 합니다(예: COSE MAC0). 또한 토큰의 구조와 마찬가지로 모듈은 [CBOR 객체 서명 및 암호화(COSE)[RFC 8152]](https://datatracker.ietf.org/doc/html/rfc8152)에서 설정한 표준을 따릅니다.

```
( // CWT Tag (Tag value: 61) --- optional    
    ( // COSE MAC0 Structure Tag (Tag value: 17) --- required        
        [            
            protectedHeaders,            
            unprotectedHeaders,            
            payload,            
            tag,        
        ]    
    )
)
```

**Example : COSE MAC0 구조를 사용한 CWT**  

```
61( // CWT tag     
    17( // COSE_MAC0 tag       
        [         
            { // Protected Headers           
                1: 4  // algorithm : HMAC-256-64         
            },         
            { // Unprotected Headers           
                4: h'53796d6d6574726963323536' // kid : Symmetric key id          
            },         
            { // Payload           
                1: "https://iss.example.com", // iss           
                2: "exampleUser", // sub           
                3: "https://aud.example.com", // aud           
                4: 1444064944, // exp           
                5: 1443944944, // nbf           
                6: 1443944944, // iat         
            },         
            h'093101ef6d789200' // tag       
        ]     
    )   
)
```
CWT 태그는 토큰을 생성할 때 선택 사항입니다. 그러나 COSE 구조 태그는 필수입니다.

## validateToken() 메서드
<a name="validatetoken-method"></a>

함수는 지정된 키를 사용하여 CWT 토큰을 디코딩하고 검증합니다. 검증에 성공하면 디코딩된 CWT 토큰을 반환합니다. 그렇지 않으면 오류가 발생합니다. 이 함수는 클레임 세트에 대한 검증을 수행하지 않습니다.

### 요청
<a name="validatetoken-request"></a>

```
cf.cwt.validateToken(token, handlerContext{key})
```Parameters

**토큰(필수)**  
검증을 위한 인코딩된 토큰입니다. JavaScript 버퍼여야 합니다.

**handlerContext(필수)**  
validateToken 직접 호출에 대한 컨텍스트를 저장하는 JavaScript 객체입니다. 현재 키 속성만 지원됩니다.

**키(필수)**  
메시지 다이제스트 계산을 위한 비밀 키입니다. 문자열 또는 JavaScript 버퍼로 제공할 수 있습니다.

### 응답
<a name="validatetoken-response"></a>

`validateToken()` 메서드가 성공적으로 검증된 토큰을 반환하면 함수의 응답은 다음 형식의 `CWTObject`입니다. 디코딩되면 모든 클레임 키가 문자열로 표시됩니다.

```
CWTObject {    
    protectedHeaders,    
    unprotectedHeaders,    
    payload
}
```

### 예제 - 토큰의 일부로 전송된 KID로 토큰 검증
<a name="validatetoken-example"></a>

이 예제는 키드가 헤더에서 추출되는 CWT 토큰 검증을 보여줍니다. 그런 다음 키드가 CloudFront Functions KeyValueStore로 전달되어 토큰을 검증하는 데 사용되는 보안 키를 가져옵니다.

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
                
        // Retrieve the secret key from the kvs
        let secretKey = await cf.kvs().get(kid);
                 
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtObj = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtObj[CwtClaims.exp] && cwtObj[CwtClaims.exp] < currentTime) {
                return {
                    statusCode: 401,
                    statusDescription: 'Token expired'
                };
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

## generateToken() 메서드
<a name="generatetoken-method"></a>

이 함수는 제공된 페이로드 및 컨텍스트 설정을 사용하여 새 CWT 토큰을 생성합니다.

### 요청
<a name="generatetoken-request"></a>

```
cf.cwt.generateToken(generatorContext, payload)
```Parameters

**generatorContext(필수)**  
이 JavaScript 객체는 토큰을 생성하기 위한 컨텍스트로 사용되며 다음 키 값 페어를 포함합니다.    
**cwtTag(선택 사항)**  
이 값은 부울로, `true`인 경우 `cwtTag`를 추가해야 함을 지정합니다.  
**coseTag(필수)**  
COSE 태그 유형을 지정합니다. 현재 `MAC0`만 지원됩니다.  
**키(필수)**  
메시지 다이제스트를 계산하는 비밀 키입니다. 이 값은 문자열 또는 JavaScript `Buffer`일 수 있습니다.

**페이로드(필수)**  
인코딩을 위한 토큰 페이로드입니다. 페이로드는 `CWTObject` 형식이어야 합니다.

### 응답
<a name="generatetoken-response"></a>

인코딩된 토큰이 포함된 JavaScript 버퍼를 반환합니다.

**Example : CWT 토큰 생성**  

```
import cf from 'cloudfront';

const CwtClaims = {
    iss: 1,
    sub: 2,
    exp: 4
};

const CatClaims = {
    catu: 401,
    catnip: 402,
    catm: 403,
    catr: 404
};

const Catu = {
    host: 1,
    path: 2,
    ext: 3
};

const CatuMatchTypes = {
    prefix_match: 1,
    suffix_match: 2,
    exact_match: 3
};

const Catr = {
    renewal_method: 1,
    next_renewal_time: 2,
    max_uses: 3
};

async function handler(event) {
    try {
        const response = {
            statusCode: 200,
            statusDescription: 'OK',
            headers: {}
        };
        
        const commonAccessToken = {
            protected: {
                1: "5",
            },
            unprotected: {},
            payload: {
                [CwtClaims.iss]: "cloudfront-documentation",
                [CwtClaims.sub]: "cwt-support-on-cloudfront-functions",
                [CwtClaims.exp]: 1740000000,
                [CatClaims.catu]: {
                    [Catu.host]: {
                        [CatuMatchTypes.suffix_match]: ".cloudfront.net"
                    },
                    [Catu.path]: {
                        [CatuMatchTypes.prefix_match]: "/media/live-stream/cf-4k/"
                    },
                    [Catu.ext]: {
                        [CatuMatchTypes.exact_match]: [
                            ".m3u8",
                            ".ts",
                            ".mpd"
                        ]
                    }
                },
                [CatClaims.catnip]: [
                    "[IP_ADDRESS]",
                    "[IP_ADDRESS]"
                ],
                [CatClaims.catm]: [
                    "GET",
                    "HEAD"
                ],
                [CatClaims.catr]: {
                    [Catr.renewal_method]: "header_renewal",
                    [Catr.next_renewal_time]: 1750000000,
                    [Catr.max_uses]: 5
                }
            }
        };
        
        if (!request.headers['x-cwt-kid']) {
            throw new Error('Missing x-cwt-kid header');
        }
        
        const kid = request.headers['x-cwt-kid'].value;
        const secretKey = await cf.kvs().get(kid);
        
        if (!secretKey) {
            throw new Error('Secret key not found for provided kid');
        }
        
        try {
            const genContext = {
                cwtTag: true,
                coseTag: "MAC0",
                key: secretKey
            };
            
            const tokenBuffer = cf.cwt.generateToken(commonAccessToken, genContext);
            response.headers['x-generated-cwt-token'] = { value: tokenBuffer.toString('base64url') };
                        
            return response;
        } catch (tokenError) {
            return {
                statusCode: 401,
                statusDescription: 'Could not generate the token'
            };
        }
    } catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
    }
}
```

**Example : 일부 로직을 기반으로 토큰 새로 고침**  

```
import cf from 'cloudfront'

const CwtClaims = {
   iss: 1,
   aud: 3,
   exp: 4
}

async function handler(event) {
    try {
        let request = event.request;
        let encodedToken = request.headers['x-cwt-token'].value;
        let kid = request.headers['x-cwt-kid'].value;
        let secretKey = await cf.kvs().get(kid); // Retrieve the secret key from the kvs
                
        // Now you can use the secretKey to decode & validate the token.
        let tokenBuffer = Buffer.from(encodedToken, 'base64url');
                
        let handlerContext = {
           key: secretKey,
        }
                
        try {
            let cwtJSON = cf.cwt.validateToken(tokenBuffer, handlerContext);
                        
            // Check if token is expired
            const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
            if (cwtJSON[CwtClaims.exp] && cwtJSON[CwtClaims.exp] < currentTime) {
                // We can regnerate the token and add 8 hours to the expiry time
                cwtJSON[CwtClaims.exp] = Math.floor(Date.now() / 1000) + (8 * 60 * 60);
                                
                let genContext = {
                  coseTag: "MAC0",
                  key: secretKey
                }
                                
                let newTokenBuffer = cf.cwt.generateToken(cwtJSON, genContext);
                 request.headers['x-cwt-regenerated-token'] = newTokenBuffer.toString('base64url');
            }
        } catch (error) {
            return {
               statusCode: 401,
               statusDescription: 'Invalid token'
            };
         }
    }
    catch (error) {
        return {
            statusCode: 402,
            statusDescription: 'Token processing failed'
        };
     }
    return request;
}
```

# 일반 헬퍼 메서드
<a name="general-helper-methods"></a>

이 페이지에서는 CloudFront Functions 내의 추가 헬퍼 메서드를 제공합니다. 이러한 메서드를 사용하려면 JavaScript 런타임 2.0을 사용하여 CloudFront Functions를 생성합니다.

```
import cf from 'cloudfront';
```

자세한 내용은 [CloudFront Functions를 위한 JavaScript 런타임 2.0 기능](functions-javascript-runtime-20.md) 섹션을 참조하세요.

## `edgeLocation` 메타데이터
<a name="edge-location-metadata"></a>

이 메서드를 사용하려면 `cloudfront` 모듈을 사용해야 합니다.

**참고**  
뷰어 요청 함수에만 이 방법을 사용할 수 있습니다. 뷰어 응답 함수의 경우 이 메서드는 비어 있습니다.

이 JavaScript 객체를 사용하여 요청을 처리하는 데 사용되는 엣지 로케이션 공항 코드, 예상 [리전 엣지 캐시](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches) 리전 또는 CloudFront 서버 IP 주소를 가져옵니다. 이 메타데이터는 뷰어 요청 이벤트 트리거만 사용할 수 있습니다.

```
cf.edgeLocation = {
    name: SEA
    serverIp: 1.2.3.4
    region: us-west-2
}
```

`cf.edgeLocation` 객체에는 다음 사항이 포함될 수 있습니다.

**이름**  
요청을 처리한 엣지 로케이션의 세 글자 [IATA 코드](https://en.wikipedia.org/wiki/IATA_airport_code)입니다.

**serverIp**  
요청을 처리한 서버의 IPv4 또는 IPv6 주소입니다.

**region**  
캐시 누락이 있는 경우 요청이 사용할 것으로 *예상되는* CloudFront 리전 엣지 캐시(REC)입니다. 이 값은 예상 REC를 사용할 수 없고 백업 REC가 요청에 사용되는 경우 업데이트되지 않습니다. 여기에는 사용 중인 Origin Shield 위치가 포함되지 않습니다. 단, 기본 REC와 Origin Shield가 동일한 위치인 경우는 예외입니다.

**참고**  
CloudFront가 오리진 장애 조치를 사용하도록 구성된 경우 CloudFront Functions는 두 번째로 간접 호출되지 않습니다. 자세한 내용은 [CloudFront 오리진 장애 조치를 통한 고가용성 최적화](high_availability_origin_failover.md) 섹션을 참조하세요.

## `rawQueryString()` 메서드
<a name="raw-query-string-method"></a>

이 메서드에는 `cloudFront` 모듈이 필요하지 않습니다.

`rawQueryString()` 메서드를 사용하여 구문 분석되지 않은 쿼리 문자열과 변경되지 않은 쿼리 문자열을 문자열로 검색합니다.

**요청**

```
function handler(event) {
    var request = event.request;
    const qs = request.rawQueryString();
}
```

**응답**

수신 요청의 전체 쿼리 문자열을 선행 `?` 없이 문자열 값으로 반환합니다.
+ 쿼리 문자열이 없지만 `?`가 있는 경우 함수는 빈 문자열을 반환합니다.
+ 쿼리 문자열이 없고 `?`가 없는 경우 함수는 `undefined`를 반환합니다.

**사례 1: 반환된 전체 쿼리 문자열(선행 `?` 없음)**  
수신 요청 URL: `https://example.com/page?name=John&age=25&city=Boston`  
`rawQueryString()`에서 를 반환합니다.`"name=John&age=25&city=Boston"`

**사례 2: 빈 문자열 반환됨(`?`가 있지만 파라미터가 없는 경우)**  
수신 요청 URL: `https://example.com/page?`  
`rawQueryString()`에서 를 반환합니다.`""`

**사례 3: `undefined` 반환됨(쿼리 문자열 및 `?` 없음)**  
수신 요청 URL: `https://example.com/page`  
`rawQueryString()`에서 를 반환합니다.`undefined`

# 함수 생성
<a name="create-function"></a>

함수는 두 단계로 생성합니다.

1. 함수 코드를 JavaScript로 생성합니다. CloudFront 콘솔의 기본 예제를 사용하거나, 직접 작성할 수 있습니다. 자세한 정보는 다음의 주제를 참조하세요.
   + [함수 코드 작성](writing-function-code.md)
   + [CloudFront 함수 이벤트 구조](functions-event-structure.md)
   + [CloudFront의 CloudFront Functions 예제](service_code_examples_cloudfront_functions_examples.md)

1. CloudFront를 사용하여 함수를 생성하고 코드를 포함합니다. 코드는 함수 내에 존재합니다(참조용이 아님).

------
#### [ Console ]

**함수를 만들려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

1. **함수 생성(Create function)**을 선택합니다.

1. AWS 계정 내에서 고유한 함수 이름을 입력한 다음 JavaScript 버전을 선택하고 **계속**을 선택합니다. 새 함수의 세부 정보 페이지가 나타납니다.
**참고**  
함수에서 [키 값 페어](kvs-with-functions.md)를 사용하려면 JavaScript 런타임 2.0을 선택해야 합니다.

1. **함수 코드** 섹션에서 **빌드** 탭을 선택하고 함수 코드를 입력합니다. **빌드** 탭에 포함된 샘플 코드는 함수 코드의 기본 구문을 보여줍니다.

1. **Save changes**(변경 사항 저장)를 선택합니다.

1. 함수 코드에서 키 값 페어를 사용하는 경우 키 값 저장소를 연결해야 합니다.

   함수를 처음 생성할 때 키 값 저장소를 연결할 수 있습니다. 또는 나중에 [함수를 업데이트](update-function.md)하여 연결할 수도 있습니다.

   지금 키 값 저장소를 연결하려면 다음 단계를 따르세요.
   + **KeyValueStore 연결** 섹션에서 **기존 KeyValueStore 연결**을 선택합니다.
   + 함수의 키 값 페어가 들어 있는 키 값 저장소를 선택한 다음 **KeyValueStore 연결**을 선택합니다.

   CloudFront는 저장소를 함수와 즉시 연결하므로 함수를 저장하지 않아도 됩니다.

------
#### [ CLI ]

CLI를 사용하는 경우 일반적으로 먼저 파일에 함수 코드를 생성한 다음 AWS CLI로 함수를 생성합니다.

**함수를 만들려면**

1. 함수 코드를 파일로 만든 다음 컴퓨터가 연결할 수 있는 디렉터리에 저장합니다.

1. 다음 예제와 같이 명령을 실행합니다. 이 예제에서는 `fileb://` 표기법을 사용하여 파일을 전달합니다. 명령을 더 쉽게 읽을 수 있도록 줄 바꿈도 포함되어 있습니다.

   ```
   aws cloudfront create-function \
       --name MaxAge \
       --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"}]}}' \
       --function-code fileb://function-max-age-v1.js
   ```
**Notes**  
`Runtime` - JavaScript의 버전입니다. 함수에 [키 값 페어](kvs-with-functions.md)를 사용하려면 버전 2.0을 지정해야 합니다.
`KeyValueStoreAssociations` - 함수에서 키 값 페어를 사용하는 경우 함수를 처음 생성할 때 키 값 저장소를 연결할 수 있습니다. 또는 `update-function`을 사용하여 나중에 연결할 수도 있습니다. 각 함수에 키 값 저장소가 하나만 연결될 수 있기 때문에 `Quantity`는 항상 `1`입니다.

   명령이 제대로 실행되면 다음과 비슷한 출력이 표시됩니다.

   ```
   ETag: ETVABCEXAMPLE
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years
       Runtime: cloudfront-js-2.0
       KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
     FunctionMetadata:
       CreatedTime: '2021-04-18T20:38:56.915000+00:00'
       FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge
       LastModifiedTime: '2023-11-19T20:38:56.915000+00:00'
       Stage: DEVELOPMENT
     Name: MaxAge
     Status: UNPUBLISHED
   Location: https://cloudfront.amazonaws.com/2020-05-31/function/arn:aws:cloudfront:::function/MaxAge
   ```

   대부분의 정보는 요청에서 반복된 내용입니다. 기타 정보는 CloudFront에 의해 추가됩니다.
**Notes**  
`ETag` - 이 값은 키 값 저장소를 수정할 때마다 변경됩니다. 나중에 이 값과 함수 이름을 사용하여 함수를 참조할 수 있습니다. 항상 현재 `ETag`를 사용하도록 하세요.
`FunctionARN` - CloudFront 함수의 ARN입니다.
111122223333 – AWS 계정입니다.
`Stage` - 함수의 스테이지(`LIVE` 또는 `DEVELOPMENT`)입니다.
`Status` - 함수의 상태(`PUBLISHED` 또는 `UNPUBLISHED`)입니다.

------

생성한 함수는 `DEVELOPMENT` 스테이지에 추가됩니다. [함수를 게시](publish-function.md)하기 전에 [함수를 테스트](test-function.md)하는 것이 좋습니다. 함수를 게시하고 나면 함수가 `LIVE` 스테이지로 변경됩니다.

# 함수 테스트
<a name="test-function"></a>

라이브 스테이지(프로덕션)에 함수를 배포하기 전에 함수를 테스트하여 의도한 대로 작동하는지 확인할 수 있습니다. 함수를 테스트하려면 CloudFront 배포가 프로덕션 환경에서 수신할 수 있는 HTTP 요청 또는 응답을 나타내는 *이벤트 객체*를 지정합니다.

CloudFront 함수는 다음을 수행합니다.

1. 제공된 이벤트 객체를 입력으로 사용하여 함수를 실행합니다.

1. 함수 로그 또는 오류 메시지 및 함수의 *컴퓨팅 사용률*과 함께 함수의 결과(수정된 이벤트 객체)를 반환합니다. 컴퓨팅 사용률에 대한 자세한 내용은 [컴퓨팅 활용 이해](#compute-utilization) 섹션을 참조하세요.

**참고**  
함수를 테스트할 때 CloudFront는 함수 실행 오류에 대해서만 검증합니다. CloudFront는 요청이 게시된 후 성공적으로 전달되는지 여부를 검증하지 않습니다. 예를 들어 함수가 필수 헤더를 삭제하면 코드에 문제가 없기 때문에 테스트가 성공합니다. 그러나 함수를 게시하고 배포와 연결하면 CloudFront를 통해 요청이 이루어질 때 함수가 실패합니다.

**Contents**
+ [

## 이벤트 객체 설정
](#test-function-create-event)
+ [

## 함수 테스트
](#test-function-step-test)
+ [

## 컴퓨팅 활용 이해
](#compute-utilization)

## 이벤트 객체 설정
<a name="test-function-create-event"></a>

함수를 테스트하기 전에 함수를 테스트할 이벤트 객체를 설정해야 합니다. 이때 여러 가지 선택지가 있습니다.

**선택 1: 이벤트 객체를 저장하지 않고 설정**  
CloudFront 콘솔의 시각적 편집기에서 이벤트 객체를 설정한 후 저장하지 않아도 됩니다.  
저장되지 않았더라도 이 이벤트 객체를 사용하여 CloudFront 콘솔에서 함수를 테스트할 수 있습니다.

**선택 2: 시각적 편집기에서 이벤트 객체 생성**  
CloudFront 콘솔의 시각적 편집기에서 이벤트 객체를 설정한 후 저장하지 않아도 됩니다. 예를 들어, 가능한 여러 입력을 테스트할 수 있도록 각 함수에 대해 10개의 이벤트 객체를 생성할 수 있습니다.  
이러한 방식으로 이벤트 객체를 생성하면 이벤트 객체를 사용하여 CloudFront 콘솔에서 함수를 테스트할 수 있습니다. AWS API 또는 SDK를 사용하여 함수를 테스트하는 데는 이벤트 객체를 사용할 수 없습니다.

**선택 3: 텍스트 편집기를 사용하여 이벤트 객체 생성**  
텍스트 편집기를 사용하여 JSON 형식으로 이벤트 객체를 만들 수 있습니다. 이벤트 객체의 구조에 대한 자세한 내용은 [이벤트 구조](functions-event-structure.md) 섹션을 참조하세요.  
이 이벤트 객체로 CLI를 사용하여 함수를 테스트할 수 있습니다. 하지만 CloudFront 콘솔에서 함수를 테스트하는 데는 사용할 수 없습니다.

**이벤트 객체를 생성하려면(옵션 1 또는 2)**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

   테스트할 함수를 선택합니다.

1. 함수 세부 정보 페이지에서 **테스트** 탭을 선택합니다.

1. **이벤트 유형**에서 다음 옵션 중 하나를 선택합니다.
   + 함수가 HTTP 요청을 수정하거나 요청에 따라 응답을 생성하는 경우 **뷰어 요청**을 선택합니다. **요청** 섹션이 나타납니다.
   + **뷰어 응답**을 선택합니다. **요청** 및 **응답** 섹션이 나타납니다.

1. 이벤트에 포함할 필드를 작성합니다. **JSON 편집**을 선택하여 원시 JSON을 확인할 수 있습니다.

1. (선택 사항) 이벤트를 저장하려면 **저장**을 선택하고 **테스트 이벤트 저장**에서 이름을 입력한 다음 **저장**을 선택합니다.

   **JSON 편집**을 선택하고 원시 JSON을 복사한 다음 CloudFront 외부의 자체 파일에 저장할 수도 있습니다.

**이벤트 객체를 생성하려면(옵션 3)**

텍스트 편집기를 사용하여 이벤트 객체를 생성합니다. 컴퓨터가 연결할 수 있는 디렉터리에 파일을 저장합니다.

다음 가이드라인을 따르도록 합니다.
+ `distributionDomainName`, `distributionId`, `requestId` 필드는 생략하세요.
+ 헤더, 쿠키, 쿼리 문자열의 이름은 소문자여야 합니다.

이러한 방식으로 이벤트 객체를 생성하는 한 가지 방법은 시각적 편집기를 사용하여 샘플을 만드는 것입니다. 샘플 형식이 올바른지 확인할 수 있습니다. 그런 다음 원시 JSON을 복사해 텍스트 편집기에 붙여넣고 파일을 저장할 수 있습니다.

이벤트의 구조에 대한 자세한 내용은 [이벤트 구조](functions-event-structure.md) 섹션을 참조하세요.

## 함수 테스트
<a name="test-function-step-test"></a>

CloudFront 콘솔 또는 AWS Command Line Interface(AWS CLI)를 사용하여 함수를 테스트할 수 있습니다.

------
#### [ Console ]

**함수를 테스트하려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

1. 테스트할 함수를 선택합니다.

1. **테스트** 탭을 선택합니다.

1. 올바른 이벤트가 표시되는지 확인합니다. 현재 표시된 이벤트에서 다른 이벤트로 전환하려면 **테스트 이벤트 선택** 필드에서 다른 이벤트를 선택하세요.

1. **함수 테스트**를 선택합니다. 콘솔에는 함수 로그와 컴퓨팅 활용을 비롯한 함수 출력이 표시됩니다.

------
#### [ CLI ]

**aws cloudfront test-function** 명령을 사용하여 함수를 테스트할 수 있습니다.

**함수를 테스트하려면**

1. 명령줄 창을 엽니다.

1. 지정된 파일이 들어 있는 디렉터리에서 다음 명령을 실행합니다.

   이 예제에서는 `fileb://` 표기법을 사용하여 이벤트 객체 파일을 전달합니다. 명령을 더 쉽게 읽을 수 있도록 줄 바꿈도 포함되어 있습니다.

   ```
   aws cloudfront test-function \
       --name MaxAge \
       --if-match ETVABCEXAMPLE \
       --event-object fileb://event-maxage-test01.json \
       --stage DEVELOPMENT
   ```
**참고**  
함수의 이름과 ETag(`if-match` 파라미터 내)로 함수를 참조합니다. 파일 시스템에서의 위치를 기준으로 이벤트 객체를 참조합니다.
스테이지는 `DEVELOPMENT` 또는 `LIVE`일 수 있습니다.

   명령이 제대로 실행되면 다음과 비슷한 출력이 표시됩니다.

   ```
   TestResult:
     ComputeUtilization: '21'
     FunctionErrorMessage: ''
     FunctionExecutionLogs: []
     FunctionOutput: '{"response":{"headers":{"cloudfront-functions":{"value":"generated-by-CloudFront-Functions"},"location":{"value":"https://aws.amazon.com/cloudfront/"}},"statusDescription":"Found","cookies":{},"statusCode":302}}'
     FunctionSummary:
       FunctionConfig:
         Comment: MaxAge function
         Runtime: cloudfront-js-2.0
         KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
       FunctionMetadata:
         CreatedTime: '2021-04-18T20:38:56.915000+00:00'
         FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge
         LastModifiedTime: '2023-17-20T10:38:57.057000+00:00'
         Stage: DEVELOPMENT
       Name: MaxAge
       Status: UNPUBLISHED
   ```

------

**참고**  
`FunctionExecutionLogs`에는 해당 함수가 `console.log()` 명령문(있는 경우)에 작성한 로그 행 목록이 포함되어 있습니다.
`ComputeUtilization`에는 함수 실행에 대한 정보가 들어 있습니다. [컴퓨팅 활용 이해](#compute-utilization)을(를) 참조하세요.
`FunctionOutput`에는 함수가 반환한 이벤트 객체가 포함됩니다.

## 컴퓨팅 활용 이해
<a name="compute-utilization"></a>

**컴퓨팅 활용(Compute utilization)**은 함수가 실행되는 데 걸린 시간의 최대 허용 시간의 백분율입니다. 예를 들어, 값이 35이면 함수가 최대 허용 시간의 35%에서 완료되었음을 의미합니다.

함수가 계속해서 최대 허용 시간을 초과할 경우 CloudFront는 해당 함수를 제한합니다. 다음 목록에서는 컴퓨팅 사용률 값에 따라 함수가 제한될 가능성을 설명합니다.

**컴퓨팅 사용률 값:**
+ **1 \$1 50** - 함수가 최대 허용 시간에 도달하기까지 많이 남았으므로 제한 없이 실행됩니다.
+ **51 \$1 70** - 함수가 최대 허용 시간에 근접하고 있습니다. 함수 코드를 최적화하는 것이 좋습니다.
+ **71 \$1 100** - 함수가 최대 허용 시간에 매우 근접하거나 최대 허용 시간을 초과합니다. 배포와 연결할 경우 CloudFront에서 이 함수를 제한할 가능성이 있습니다.

# 함수 업데이트
<a name="update-function"></a>

함수는 언제든지 업데이트할 수 있습니다. `DEVELOPMENT` 스테이지에 있는 함수 버전만 변경됩니다. 업데이트를 `DEVELOPMENT` 스테이지에서 `LIVE`로 복사하려면 [함수를 게시](publish-function.md)해야 합니다.

CloudFront 콘솔 또는 AWS Command Line Interface(AWS CLI)를 사용하여 함수의 코드를 업데이트할 수 있습니다.

------
#### [ Console ]

**함수 코드를 업데이트하려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

   업데이트할 함수를 선택합니다.

1. **편집**을 선택하고 다음과 같이 변경합니다.
   + **세부 정보** 섹션의 모든 필드를 업데이트합니다.
   + 연결된 키 값 저장소를 변경하거나 제거합니다. 키 값 저장소에 대한 자세한 내용은 [Amazon CloudFront KeyValueStore](kvs-with-functions.md) 섹션을 참조하세요.
   + 함수 코드를 변경합니다. **빌드** 탭을 선택하고 필요한 부분을 변경한 다음 **변경 사항 저장**을 선택하여 코드의 변경 사항을 저장합니다.

------
#### [ CLI ]

**함수 코드를 업데이트하려면**

1. 명령줄 창을 엽니다.

1. 다음 명령을 실행합니다.

   이 예제에서는 `fileb://` 표기법을 사용하여 파일을 전달합니다. 명령을 더 쉽게 읽을 수 있도록 줄 바꿈도 포함되어 있습니다.

   ```
   aws cloudfront update-function \
       --name MaxAge \
       --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"}]}}' \
       --function-code fileb://function-max-age-v1.js \
       --if-match ETVABCEXAMPLE
   ```
**참고**  
함수의 이름과 ETag(`if-match` 파라미터 내)로 함수를 식별할 수 있습니다. 현재 ETag를 사용하도록 하세요. [DescribeFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeFunction.html) API 작업에서 이 값을 얻을 수 있습니다.
변경하지 않을 때에도 `function-code`가 포함되어야 합니다.
`function-config`에 유의하세요. 구성에 유지하려는 모든 내용을 전달해야 합니다. 특히 키 값 저장소는 다음과 같이 처리하세요.  
기존 키 값 저장소 연결(있는 경우)을 유지하려면 **기존 저장소의 이름을 지정합니다.
연결을 변경하려면 **새 키 값 저장소의 이름을 지정합니다.
연결을 제거하려면 `KeyValueStoreAssociations` 파라미터를 생략하세요.

   명령이 제대로 실행되면 다음과 비슷한 출력이 표시됩니다.

   ```
   ETag: ETVXYZEXAMPLE
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years \
       Runtime: cloudfront-js-2.0 \
       KeyValueStoreAssociations= \
         {Quantity=1, \
         Items=[{KeyValueStoreARN='arn:aws:cloudfront::111122223333:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111'}]} \
     FunctionMetadata: \
       CreatedTime: '2021-04-18T20:38:56.915000+00:00' \
       FunctionARN: arn:aws:cloudfront::111122223333:function/MaxAge \
       LastModifiedTime: '2023-12-19T23:41:15.389000+00:00' \
       Stage: DEVELOPMENT \
     Name: MaxAge \
     Status: UNPUBLISHED
   ```

------

대부분의 정보는 요청에서 반복된 내용입니다. 기타 정보는 CloudFront에 의해 추가됩니다.

**참고**  
`ETag` - 이 값은 키 값 저장소를 수정할 때마다 변경됩니다.
`FunctionARN` - CloudFront 함수의 ARN입니다.
`Stage` - 함수의 스테이지(`LIVE` 또는 `DEVELOPMENT`)입니다.
`Status` - 함수의 상태(`PUBLISHED` 또는 `UNPUBLISHED`)입니다.

# 함수 게시
<a name="publish-function"></a>

함수를 게시하면 `DEVELOPMENT` 스테이지에서 `LIVE` 스테이지로 함수가 복사됩니다.

함수와 연결된 캐시 동작이 없는 경우 이를 게시하면 캐시 동작과 연결할 수 있습니다. 캐시 동작은 `LIVE` 스테이지에 있는 함수에만 연결할 수 있습니다.

**중요**  
함수를 게시하기 전에 [함수를 테스트](test-function.md)하는 것이 좋습니다.
함수를 게시하면 배포가 완료되는 즉시 해당 함수와 연결된 모든 캐시 동작이 새로 게시된 복사본을 사용하여 자동으로 시작됩니다.

CloudFront 콘솔 또는 AWS CLI를 사용하여 함수를 게시할 수 있습니다.

------
#### [ Console ]

**함수를 게시하려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

1. 업데이트할 함수를 선택합니다.

1. **게시** 탭을 선택한 다음 **게시**를 선택합니다. 함수가 하나 이상의 캐시 동작에 이미 연결되어 있는 경우 **게시 및 업데이트**를 선택합니다.

1. (선택 사항) 해당 함수와 연결된 배포를 보려면 **연결된 CloudFront 배포**(Associated CloudFront distributions)를 선택하여 해당 섹션을 확장합니다.

성공하면 페이지 상단에 ***함수 이름*이 성공적으로 게시**되었다는 배너가 표시됩니다. **빌드**(Build) 탭을 선택한 다음 **라이브**(Live)를 선택하여 함수 코드의 라이브 버전을 볼 수도 있습니다.

------
#### [ CLI ]

**함수를 게시하려면**

1. 명령줄 창을 엽니다.

1. 다음 **aws cloudfront publish-function** 명령을 실행합니다. 이 예에서는 예제를 보다 읽기 쉽도록 줄 바꿈이 제공됩니다.

   ```
   aws cloudfront publish-function \
       --name MaxAge \
       --if-match ETVXYZEXAMPLE
   ```

   명령이 제대로 실행되면 다음과 비슷한 출력이 표시됩니다.

   ```
   FunctionSummary:
     FunctionConfig:
       Comment: Max Age 2 years
       Runtime: cloudfront-js-2.0
     FunctionMetadata:
       CreatedTime: '2021-04-18T21:24:21.314000+00:00'
       FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
       LastModifiedTime: '2023-12-19T23:41:15.389000+00:00'
       Stage: LIVE
     Name: MaxAge
     Status: UNASSOCIATED
   ```

------

# 배포에 함수 연결
<a name="associate-function"></a>

배포에 함수를 사용하려면 함수를 배포의 하나 이상의 캐시 동작과 연결합니다. 여러 배포에서 여러 캐시 동작과 함수를 연결할 수 있습니다.

함수는 다음 중 무엇과도 연결할 수 있습니다.
+ 기존 캐시 동작
+ 기존 배포의 새로운 캐시 동작
+ 새 배포의 새로운 캐시 동작

함수를 캐시 동작과 연결할 때는 *이벤트 유형*(event type)을 선택해야 합니다. 이벤트 유형에 따라 CloudFront가 함수를 실행하는 시기가 결정됩니다.

다음과 같은 이벤트 유형을 선택할 수 있습니다.
+ **최종 사용자 요청** – 이 함수는 CloudFront가 최종 사용자의 요청을 수신할 때 실행됩니다.
+ **최종 사용자 응답** – 이 함수는 CloudFront가 최종 사용자에게 응답을 반환하기 전에 실행됩니다.

CloudFront Functions와 함께 오리진 관련 이벤트 유형(*오리진 요청* 및 *오리진 응답*)을 사용할 수 없습니다. 대신 Lambda@Edge를 사용할 수 있습니다. 자세한 내용은 [Lambda@Edge 함수를 트리거할 수 있는 CloudFront 이벤트](lambda-cloudfront-trigger-events.md) 단원을 참조하십시오.

**참고**  
함수를 연결하기 전에 [`LIVE` 스테이지에 게시](publish-function.md)해야 합니다.

CloudFront 콘솔 또는 AWS Command Line Interface(AWS CLI)를 사용하여 배포에 함수를 연결할 수 있습니다. 다음 절차에서는 함수를 기존 캐시 동작에 연결하는 방법을 보여 줍니다.

------
#### [ Console ]

**기존 캐시 동작에 함수를 연결하려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

1. 연결할 함수를 선택합니다.

1. **함수** 페이지에서 **게시** 탭을 선택합니다.

1. **Publish 함수**를 선택합니다.

1. **연결 추가**를 선택합니다. 표시되는 대화 상자에서 배포, 이벤트 유형 및/또는 캐시 동작을 선택합니다.

   이벤트 유형에서 함수를 실행할 시기를 선택합니다.
   + **뷰어 요청** - CloudFront가 요청을 수신할 때마다 이 함수를 실행합니다.
   + **뷰어 응답** - CloudFront가 응답을 반환할 때마다 이 함수를 실행합니다.

1. 구성을 저장하려면 **연결 추가**를 선택합니다.

CloudFront가 배포를 함수와 연결합니다. 연결된 배포가 배포될 때까지 몇 분 정도 기다립니다. 함수 세부 정보 페이지에서 **배포 보기**를 선택하여 진행 상황을 확인할 수 있습니다.

------
#### [ CLI ]

**기존 캐시 동작에 함수를 연결하려면**

1. 명령줄 창을 엽니다.

1. 함수에 연결할 캐시 동작을 가진 배포에 대한 배포 구성을 저장하려면 다음 명령을 입력합니다. 이 명령은 배포 구성을 `dist-config.yaml`이라는 이름의 파일에 저장합니다. 이 명령을 사용하려면 다음을 수행합니다.
   + *`DistributionID`*를 해당 배포의 ID로 바꿉니다.
   + 한 줄로 명령을 실행합니다. 이 예에서는 예제를 보다 읽기 쉽도록 줄 바꿈이 제공됩니다.

   ```
   aws cloudfront get-distribution-config \
       --id DistributionID \
       --output yaml > dist-config.yaml
   ```

   명령이 성공하면 AWS CLI는 출력을 반환하지 않습니다.

1. 생성한 `dist-config.yaml`이라는 파일을 엽니다. 파일을 편집하여 다음과 같이 변경합니다.

   1. `ETag` 필드의 이름을 `IfMatch`로 바꾸지만 필드 값은 변경하지 마세요.

   1. 캐시 동작에서 `FunctionAssociations`(이)라는 이름의 객체를 찾습니다. 함수 연결을 추가하려면 이 객체를 업데이트합니다. 함수 연결에 대한 YAML 구문은 다음 예제와 같습니다.
      + 다음 예제에서는 최종 사용자 요청 이벤트 객체를 보여줍니다. 최종 사용자 응답 이벤트 유형을 사용하려면 `viewer-request`을(를)`viewer-response`(으)로 바꿉니다.
      + *`arn:aws:cloudfront::111122223333:function/ExampleFunction`*을 이 캐시 동작에 연결하려는 함수의 Amazon 리소스 이름(ARN)으로 바꿉니다. 함수 ARN을 얻으려면 **aws cloudfront list-functions** 명령을 사용할 수 있습니다.

      ```
      FunctionAssociations:
        Items:
          - EventType: viewer-request
            FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
        Quantity: 1
      ```

   1. 이러한 변경을 수행한 후 파일을 저장합니다.

1. 다음 명령을 사용하여 배포를 업데이트하고 함수 연결을 추가합니다. 이 명령을 사용하려면 다음을 수행합니다.
   + *`DistributionID`*를 해당 배포의 ID로 바꿉니다.
   + 한 줄로 명령을 실행합니다. 이 예에서는 예제를 보다 읽기 쉽도록 줄 바꿈이 제공됩니다.

   ```
   aws cloudfront update-distribution \
       --id DistributionID \
       --cli-input-yaml file://dist-config.yaml
   ```

   명령이 성공하면 함수 연결로 방금 업데이트된 배포를 설명하는 다음과 같은 출력이 표시됩니다. 다음 예제 출력은 가독성을 위해 잘립니다.

   ```
   Distribution:
     ARN: arn:aws:cloudfront::111122223333:distribution/EBEDLT3BGRBBW
     ... truncated ...
     DistributionConfig:
       ... truncated ...
       DefaultCacheBehavior:
         ... truncated ...
         FunctionAssociations:
           Items:
           - EventType: viewer-request
             FunctionARN: arn:aws:cloudfront::111122223333:function/ExampleFunction
           Quantity: 1
         ... truncated ...
     DomainName: d111111abcdef8.cloudfront.net
     Id: EDFDVBD6EXAMPLE
     LastModifiedTime: '2021-04-19T22:39:09.158000+00:00'
     Status: InProgress
   ETag: E2VJGGQEG1JT8S
   ```

------

배포가 재배포되는 동안 배포의 `Status`가 `InProgress`로 변경됩니다. 새 배포 구성이 CloudFront 엣지 로케이션에 도달하면 해당 엣지 로케이션에 연결된 함수를 사용하기 시작합니다. 배포가 완전히 완료되면 `Status`가 다시 `Deployed`로 바뀝니다. 이는 연결된 CloudFront 함수가 전 세계의 모든 CloudFront 엣지 로케이션에서 작동함을 나타냅니다. 이 작업은 일반적으로 몇 분 정도 걸립니다.

# Amazon CloudFront KeyValueStore
<a name="kvs-with-functions"></a>

CloudFront KeyValueStore는 [CloudFront 함수](cloudfront-functions.md) 내에서 읽기 액세스를 허용하는 안전한 글로벌 키 값 데이터 스토어로, CloudFront 엣지 로케이션에서 고급 사용자 지정 로직을 사용할 수 있습니다.

CloudFront KeyValueStore를 사용하면 함수 코드를 업데이트하고 함수와 관련된 데이터를 서로 독립적으로 업데이트할 수 있습니다. 이렇게 분리하면 함수 코드가 간소화되고 코드 변경 사항을 배포할 필요 없이 데이터를 쉽게 업데이트할 수 있습니다.

**참고**  
[CloudFront KeyValueStore를 사용하려면 CloudFront 함수가 JavaScript 런타임 2.0](functions-javascript-runtime-20.md)을 사용해야 합니다.

키 값 페어를 사용하는 일반적인 절차는 다음과 같습니다.
+ 키 값 저장소를 만들고 키 값 페어 모음으로 채웁니다. Amazon S3 버킷에 키 값 스토어를 추가하거나 수동으로 입력할 수 있습니다.
+ 키 값 스토어를 CloudFront 함수와 연결합니다.
+ 함수 코드 내에서 키 이름을 사용하여 키와 관련된 값을 검색하거나 키가 존재하는지 알아볼 수 있습니다. 함수 코드에서 키 값 페어를 사용하는 방법과 도우미 메서드에 대한 자세한 내용은 [키 값 저장소를 위한 도우미 메서드](functions-custom-methods.md) 섹션을 참조하세요.

## 사용 사례
<a name="key-value-store-use-cases"></a>

다음 예제에 키 값 페어를 사용할 수 있습니다.
+ **URL 재작성 또는 리디렉션** - 키 값 페어에는 재작성된 URL 또는 리디렉션 URL이 포함될 수 있습니다.
+ **A/B 테스트 및 기능 플래그** - 웹사이트의 특정 버전에 트래픽 비율을 할당하여 실험을 실행하는 함수를 만들 수 있습니다.
+ **액세스 권한 부여** - 사용자가 정의한 기준과 KeyValueStore에 저장된 데이터에 따라 요청을 허용하거나 거부하는 액세스 제어를 구현할 수 있습니다.

## 지원되는 값 형식
<a name="key-value-store-supported-formats"></a>

키 값 페어의 값은 다음 형식 중 하나로 저장할 수 있습니다.
+ 문자열
+ 바이트로 인코딩된 문자열
+ JSON 

## 보안
<a name="key-value-store-security"></a>

CloudFront Functions 및 모든 키 값 저장소 데이터는 다음과 같이 안전하게 처리됩니다.
+ CloudFront는 저장 중이거나 전송 중(키 값 스토어를 읽거나 쓸 때)인 각 키 값 스토어를 [CloudFront KeyValueStore](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_Operations_Amazon_CloudFront_KeyValueStore.html) API 작업을 직접 호출할 때 암호화합니다.
+ 함수를 실행할 때 CloudFront는 CloudFront 엣지 로케이션의 메모리에 있는 각 키 값 페어를 복호화합니다.

CloudFront KeyValueStore를 시작하려면 다음 주제를 참조하세요.

**Topics**
+ [

## 사용 사례
](#key-value-store-use-cases)
+ [

## 지원되는 값 형식
](#key-value-store-supported-formats)
+ [

## 보안
](#key-value-store-security)
+ [

# 키 값 저장소 사용
](kvs-with-functions-kvs.md)
+ [

# 키 값 데이터로 작업
](kvs-with-functions-kvp.md)
+ CloudFront 키 값 저장소 시작 방법에 대한 자세한 내용은 [Introducing Amazon CloudFront KeyValueStore](https://aws.amazon.com/blogs/aws/introducing-amazon-cloudfront-keyvaluestore-a-low-latency-datastore-for-cloudfront-functions/) AWS 블로그 게시물을 참조하세요.

# 키 값 저장소 사용
<a name="kvs-with-functions-kvs"></a>

CloudFront Functions에서 사용하려는 키 값 페어를 보관할 키 값 저장소를 생성해야 합니다.

키 값 저장소를 생성하고 키-값 페어를 추가한 후 CloudFront 함수 코드에서 키 값을 사용할 수 있습니다.

시작하려면 다음 주제를 참조하세요.

**Topics**
+ [

# 키 값 저장소 생성
](kvs-with-functions-create.md)
+ [

# 키 값 저장소를 함수와 연결
](kvs-with-functions-associate.md)
+ [

# 키 값 저장소 업데이트
](kvs-with-functions-edit.md)
+ [

# 키 값 저장소에 대한 참조 가져오기
](kvs-with-functions-get-reference.md)
+ [

# 키 값 저장소 삭제
](kvs-with-functions-delete.md)
+ [

# 키 값 페어의 파일 형식
](kvs-with-functions-create-s3-kvp.md)

**참고**  
JavaScript 런타임 2.0에는 함수 코드의 키 값으로 작업하기 위한 몇 가지 도우미 메서드가 포함되어 있습니다. 자세한 내용은 [키 값 저장소를 위한 도우미 메서드](functions-custom-methods.md) 섹션을 참조하세요.

# 키 값 저장소 생성
<a name="kvs-with-functions-create"></a>



키 값 저장소와 키 값 페어를 동시에 생성할 수 있습니다. 또한 비어 있는 키 값 저장소를 만든 다음 나중에 키 값 페어를 추가할 수 있습니다.

**참고**  
Amazon S3 버킷에서 데이터 소스를 지정하는 경우 해당 버킷에 대한 `s3:GetObject` 및 `s3:GetBucketLocation` 권한이 있어야 합니다. 이러한 권한이 없는 경우 CloudFront는 키 값 저장소를 성공적으로 생성할 수 없습니다.

키 값 저장소를 생성하면서 키 값 페어를 동시에 추가할지 여부를 결정하세요. CloudFront 콘솔, CloudFront API 또는 AWS SDK를 사용하여 키 값 페어를 가져올 수 있습니다. 그러나 키 값 저장소를 **처음 만들 때만 키 값 페어 파일을 가져올 수 있습니다.

키 값 페어로 구성된 파일을 생성하려면 [키 값 페어의 파일 형식](kvs-with-functions-create-s3-kvp.md) 섹션을 참조하세요.

------
#### [ Console ]

**키 값 저장소를 생성하려면**

1. AWS Management Console에 로그인하고 [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions)에 있는 CloudFront 콘솔에서 **함수** 페이지를 엽니다.

1. **KeyValueStores** 탭을 선택한 다음 **KeyValueStore 생성**을 선택합니다.

1. 키 값 저장소 이름을 입력하고 필요한 경우 설명을 입력합니다.

1. **S3 URI** 작성: 
   + 키 값 페어 파일이 있는 경우 파일을 저장한 Amazon S3 버킷의 경로를 입력합니다.
   + 키 값 페어를 수동으로 입력하려는 경우 이 필드를 비워 두세요.

1. **생성(Create)**을 선택합니다. 키 값 저장소가 생겼습니다.

   새로운 키 값 저장소의 세부 정보 페이지가 나타납니다. 페이지의 정보에는 키 값 저장소의 ID 및 ARN이 포함됩니다.
   + ID는 AWS 계정에서 고유한 임의의 문자열입니다.
   + ARN의 구문은 다음과 같습니다.

     *AWS 계정*`:key-value-store/`*키 값 저장소 ID*

1. **키 값 페어** 섹션을 살펴보세요. 파일을 가져온 경우 이 섹션에 일부 키 값 페어가 표시됩니다. 다음을 수행할 수 있습니다.
   + 파일을 가져온 경우 직접 값을 더 추가할 수도 있습니다.
   + Amazon S3 버킷에서 파일을 가져오지 않았고 지금 키 값 페어를 추가하려는 경우 다음 단계를 완료하면 됩니다.
   + 이 단계를 건너뛰고 나중에 키 값 페어를 추가할 수 있습니다.

1. 지금 페어를 추가하려면 다음 단계를 따르세요.

   1. **키 값 페어 추가**를 선택합니다.

   1. **페어 추가**를 선택하고 이름과 값을 입력합니다. 태그를 더 추가하려면 이 단계를 반복합니다.

   1. 작업을 마쳤으면 **변경 사항 저장**을 선택하여 모든 키 값 페어를 키 값 저장소에 저장합니다. 나타나는 대화 상자에서 **완료**를 선택합니다.

1. 지금 키 값 저장소를 함수와 연결하려면 **연결된 함수** 섹션을 완료하세요. 자세한 내용은 [함수 생성](create-function.md) 또는 [함수 업데이트](update-function.md) 섹션을 참조하세요.

   나중에 이 키 값 저장소 세부 정보 페이지 또는 함수 세부 정보 페이지에서 함수를 연결할 수도 있습니다.

------
#### [ AWS CLI ]

**키 값 저장소를 생성하려면**
+ 다음 명령을 실행하여 키 값 저장소를 생성하고 Amazon S3 버킷에서 키 값 페어를 가져옵니다.

  ```
  aws cloudfront create-key-value-store \
      --name=keyvaluestore1 \
      --comment="This is my key value store file" \
      --import-source=SourceType=S3,SourceARN=arn:aws:s3:::amzn-s3-demo-bucket1/kvs-input.json
  ```

  **응답**

  ```
  {
      "ETag": "ETVABCEXAMPLE",
      "Location": "https://cloudfront.amazonaws.com/2020-05-31/key-value-store/arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
      "KeyValueStore": {
          "Name": "keyvaluestore1",
          "Id": "8aa76c93-3198-462c-aaf6-example",
          "Comment": "This is my key value store file",
          "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
          "Status": "PROVISIONING",
          "LastModifiedTime": "2024-08-06T22:19:10.813000+00:00"
      }
  }
  ```

------
#### [ API ]

**키 값 저장소를 생성하려면**

1. [CloudFront CreateKeyValueStore](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateKeyValueStore.html) 작업을 사용합니다. 이 작업에는 다음과 같은 몇 가지 파라미터가 사용됩니다.
   + 키 값 저장소의 `name`
   + 설명이 포함된 `comment` 파라미터
   + Amazon S3 버킷에 저장된 파일에서 키 값 페어를 가져올 수 있는 `import-source` 파라미터. 키 값 저장소를 처음 만들 때만 파일에서 키 값 페어를 가져올 수 있습니다. 파일 구조에 대한 자세한 내용은 [키 값 페어의 파일 형식](kvs-with-functions-create-s3-kvp.md) 섹션을 참조하세요.

작업 응답에는 다음 정보가 포함됩니다.
+ 지정한 이름을 포함하여 요청에 전달된 값
+ 생성 시간 등의 데이터
+ `ETag`(예: `ETVABCEXAMPLE`), 키 값 저장소의 이름을 포함하는 ARN(예: `arn:aws:cloudfront::123456789012:key-value-store/keyvaluestore1`) 

  `ETag`, ARN 및 이름을 조합하여 키 값 저장소를 프로그래밍 방식으로 사용할 수 있습니다.

------

## 키 값 저장소 상태
<a name="key-value-store-status"></a>

키 값 저장소를 생성할 때 데이터 저장소는 다음과 같은 상태 값을 가질 수 있습니다.


****  

| 값 | 설명 | 
| --- | --- | 
|  **프로비저닝**  |  키 값 저장소가 생성되었으며 CloudFront는 지정된 데이터 소스를 처리하고 있습니다.  | 
|  **준비됨**  |  키 값 저장소가 생성되고 CloudFront가 지정한 데이터 소스를 성공적으로 처리했습니다.  | 
|  **가져오기에 실패했습니다**  |  CloudFront는 지정한 데이터 소스를 처리하지 못했습니다. 파일 형식이 유효하지 않거나 크기 제한을 초과하는 경우 이 상태가 나타날 수 있습니다. 자세한 내용은 [키 값 페어의 파일 형식](kvs-with-functions-create-s3-kvp.md) 섹션을 참조하세요.  | 

# 키 값 저장소를 함수와 연결
<a name="kvs-with-functions-associate"></a>

키 값 저장소를 생성한 후 함수를 업데이트하여 키 값 저장소와 연결할 수 있습니다. 해당 함수에서 해당 저장소의 키 값 페어를 사용하려면 이 연결을 만들어야 합니다. 다음 규칙이 적용됩니다.
+ 함수 하나에는 키 값 저장소가 하나만 있을 수 있습니다.
+ 동일한 키 값 저장소를 여러 함수와 연결할 수 있습니다.

------
#### [ Console ]

**키 값 저장소를 함수와 연결하려면**

1. CloudFront 콘솔([https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions))에 로그인하고 **함수** 페이지를 엽니다.

1. 함수 이름을 선택합니다.

1. **KeyValueStore 연결** 섹션에서 **기존 KeyValueStore 연결**을 선택합니다.

1. 함수의 키 값 페어가 들어 있는 키 값 저장소를 선택한 다음 **KeyValueStore 연결**을 선택합니다.

   CloudFront는 저장소를 함수와 즉시 연결하므로 함수를 저장하지 않아도 됩니다.

1. 다른 키 값 저장소를 지정하려면 **연결된 KeyValueStore 업데이트**를 선택하고 다른 키 값 저장소 이름을 선택한 다음 **KeyValueStore 연결**을 선택합니다.

자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.

------
#### [ AWS CLI ]

**키 값 저장소를 함수와 연결하려면**
+ 다음 명령을 실행하여 `MaxAge` 함수를 업데이트하고 키 값 저장소 리소스를 연결합니다.

  ```
  aws cloudfront update-function \
      --name MaxAge \
      --function-config '{"Comment":"Max Age 2 years","Runtime":"cloudfront-js-2.0","KeyValueStoreAssociations":{"Quantity":1,"Items":[{"KeyValueStoreARN":"arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example"}]}}' \
      --function-code fileb://function-max-age-v1.js \
      --if-match ETVABCEXAMPLE
  ```
+ 키 값 저장소를 함수와 연결하려면 `KeyValueStoreAssociations` 파라미터 및 키 값 저장소 ARN을 지정합니다.
+ 연결을 변경하려면 다른 키 값 저장소의 이름을 지정합니다.
+ 연결을 제거하려면 `KeyValueStoreAssociations` 파라미터를 제거합니다.

자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.

------
#### [ API ]

**키 값 저장소를 함수와 연결하려면**
+ [UpdateFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateFunction.html) API 작업을 사용합니다. 자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.

------

**참고**  
키 값 페어를 변경하지 않고 키 값 저장소를 수정하거나 키 값 저장소에서 키 값 페어만 수정하는 경우 키 값 저장소를 다시 연결할 필요가 없습니다. 또한 함수를 다시 게시할 필요도 없습니다.  
그러나 함수를 테스트하여 예상대로 작동하는지 확인하는 것이 좋습니다. 자세한 내용은 [함수 테스트](test-function.md) 섹션을 참조하세요.
특정 키 값 저장소를 사용하는 모든 함수를 확인할 수 있습니다. CloudFront 콘솔에서 키 값 저장소 세부 정보 페이지를 선택합니다.

# 키 값 저장소 업데이트
<a name="kvs-with-functions-edit"></a>

키 값 저장소를 업데이트하는 경우 키 값 페어를 변경하거나 키 값 저장소와 함수 간의 연결을 변경할 수 있습니다.

------
#### [ Console ]

**키 값 저장소를 업데이트하려면**

1. AWS Management Console에 로그인하고 [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions)에 있는 CloudFront 콘솔에서 **함수** 페이지를 엽니다.

1. **KeyValueStore** 탭을 선택합니다.

1.  업데이트할 키 값 저장소를 선택합니다.
   + 키 값 페어를 업데이트하려면 **키 값 페어** 섹션에서 **편집**을 선택합니다. 키 값 페어를 추가하거나 삭제할 수 있습니다. 기존 키 값 페어의 값을 변경할 수도 있습니다. 작업을 마쳤으면 **변경 내용 저장**을 선택합니다.
   + 이 키 값 저장소에 대한 연결을 업데이트하려면 **함수로 이동**을 선택합니다. 자세한 내용은 [키 값 저장소를 함수와 연결](kvs-with-functions-associate.md) 섹션을 참조하세요.

------
#### [ AWS CLI ]

**키 값 저장소를 업데이트하려면**

1. **키 값 페어 변경** - 키 값 페어를 더 추가하고, 하나 이상의 키 값 페어를 삭제하고, 기존 키 값 페어의 값을 변경할 수 있습니다. 자세한 내용은 [키 값 데이터로 작업](kvs-with-functions-kvp.md) 섹션을 참조하세요.

1. **키 값 저장소의 함수 연결 변경** - 키 값 저장소의 함수 연결을 업데이트하려면 [키 값 저장소를 함수와 연결](kvs-with-functions-associate.md) 섹션을 참조하세요.
**작은 정보**  
키 값 저장소의 ARN이 필요합니다. 자세한 내용은 [키 값 저장소에 대한 참조 가져오기](kvs-with-functions-get-reference.md) 섹션을 참조하세요.

------
#### [ API ]

**키 값 저장소를 업데이트하려면**

1. **키 값 페어 변경** - 키 값 페어를 더 추가하고, 하나 이상의 키 값 페어를 삭제하고, 기존 키 값 페어의 값을 변경할 수 있습니다. 자세한 내용은 [키 값 데이터로 작업](kvs-with-functions-kvp.md) 섹션을 참조하세요.

1. **키 값 저장소의 함수 연결 변경** - 키 값 저장소의 함수 연결을 업데이트하려면 [UpdateFunction](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateFunction.html) API 작업을 사용하세요. 자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.
**작은 정보**  
키 값 저장소의 ARN이 필요합니다. 자세한 내용은 [키 값 저장소에 대한 참조 가져오기](kvs-with-functions-get-reference.md) 섹션을 참조하세요.

------

# 키 값 저장소에 대한 참조 가져오기
<a name="kvs-with-functions-get-reference"></a>

프로그래밍 방식으로 키 값 저장소를 사용하려면 `ETag`와 키 값 저장소의 이름이 필요합니다.

두 값을 모두 가져오려면 AWS Command Line Interface(AWS CLI) 또는 CloudFront API를 사용할 수 있습니다.

------
#### [ AWS CLI ]

**키 값 저장소 참조를 가져오려면**

1. 키 값 저장소 목록을 반환하려면 다음 명령을 실행합니다. 변경할 키 값 저장소의 이름을 찾습니다.

   ```
   aws cloudfront list-key-value-stores
   ```

1. 응답에서 원하는 키 값 저장소의 이름을 찾습니다.

   **응답**

   ```
   {
       "KeyValueStoreList": {
           "Items": [
               {
                   "Name": "keyvaluestore3",
                   "Id": "37435e19-c205-4271-9e5c-example3",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example3",
                   "Status": "READY",
                   "LastModifiedTime": "2024-05-08T14:50:18.876000+00:00"
               },
               {
                   "Name": "keyvaluestore2",
                   "Id": "47970d59-6408-474d-b850-example2",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/47970d59-6408-474d-b850-example2",
                   "Status": "READY",
                   "LastModifiedTime": "2024-05-30T21:06:22.113000+00:00"
               },
               {
                   "Name": "keyvaluestore1",
                   "Id": "8aa76c93-3198-462c-aaf6-example",
                   "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
                   "Status": "READY",
                   "LastModifiedTime": "2024-08-06T22:19:30.510000+00:00"
               }
           ]
       }
   }
   ```

1. 다음 명령을 실행하여 지정된 키 값 저장소의 `ETag`를 반환합니다.

   ```
   aws cloudfront describe-key-value-store \
       --name=keyvaluestore1
   ```

   **응답**

   ```
   {
       "ETag": "E3UN6WX5RRO2AG",
       "KeyValueStore": {
           "Name": "keyvaluestore1",
           "Id": "8aa76c93-3198-462c-aaf6-example",
           "Comment": "This is an example KVS",
           "ARN": "arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example",
           "Status": "READY",
           "LastModifiedTime": "2024-08-06T22:19:30.510000+00:00"
       }
   }
   ```

------
#### [ API ]

**키 값 저장소 참조를 가져오려면**

1. [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html) API 작업을 사용하여 키 값 저장소 목록을 반환합니다. 변경할 키 값 저장소의 이름을 찾습니다.

1. [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DescribeKeyValueStore.html) API 작업을 사용하여 이전 단계에서 반환한 키 값 저장소의 이름을 지정합니다.

------

응답에는 UUID, 키 값 저장소의 ARN, 키 값 저장소의 `ETag`가 포함됩니다.
+ `ETag`(예: `E3UN6WX5RRO2AG`)
+ UUID는 128비트임(예: `8aa76c93-3198-462c-aaf6-example`)
+ 다음 예와 같이 ARN에는 AWS 계정 번호, 상수 `key-value-store`, UUID가 포함됩니다.

  `arn:aws:cloudfront::123456789012:key-value-store/8aa76c93-3198-462c-aaf6-example`

`DescribeKeyValueStore` 작업에 대한 자세한 내용은 [CloudFront KeyValueStore 소개](kvs-with-functions-kvp.md#kvs-with-functions-api-describe) 섹션을 참조하세요.

# 키 값 저장소 삭제
<a name="kvs-with-functions-delete"></a>

Amazon CloudFront 콘솔 또는 API를 사용하여 키 값 저장소를 삭제할 수 있습니다.

------
#### [ Console ]

**키 값 저장소를 삭제하려면**

1. AWS Management Console에 로그인하고 [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions)에 있는 CloudFront 콘솔에서 **함수** 페이지를 엽니다.

1. 함수 이름을 선택합니다.

1. **연결된 KeyValueStore** 섹션에서 키 값 저장소가 함수와 연결되어 있는지 확인합니다. 연결되어 있는 경우 **KeyValueStore 연결 해제**를 선택한 다음 **연결 제거**를 선택하여 연결을 제거합니다.

1. 탐색 창에서 **함수** 페이지를 선택한 다음 **KeyValueStores** 탭을 선택합니다.

1. 삭제하려는 키 값 저장소를 선택한 다음 **삭제**를 선택합니다.

------
#### [ AWS CLI ]

**키 값 저장소를 삭제하려면**

1. `ETag`와 키 값 저장소의 이름을 가져옵니다. 자세한 내용은 [키 값 저장소에 대한 참조 가져오기](kvs-with-functions-get-reference.md) 섹션을 참조하세요.

1. 키 값 저장소가 함수와 연결되어 있는지 확인합니다. 연결되어 있는 경우 연결이 삭제됩니다. 이 두 단계에 대한 자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.

1. 키 값 저장소의 이름과 `ETag`를 가져왔고 키 값 저장소가 함수와 더 이상 연결되지 않은 경우 해당 저장소를 삭제할 수 있습니다.

   다음 명령을 실행하여 지정된 키 값 저장소를 삭제합니다.

   ```
   aws cloudfront delete-key-value-store \
       --name=keyvaluestore1 \
       --if-match=E3UN6WX5RRO2AG
   ```

------
#### [ API ]

**키 값 저장소를 삭제하려면**

1. `ETag`와 키 값 저장소의 이름을 가져옵니다. 자세한 내용은 [키 값 저장소에 대한 참조 가져오기](kvs-with-functions-get-reference.md) 섹션을 참조하세요.

1. 키 값 저장소가 함수와 연결되어 있는지 확인합니다. 연결되어 있는 경우 연결이 삭제됩니다. 이 두 단계에 대한 자세한 내용은 [함수 업데이트](update-function.md) 섹션을 참조하세요.

1. 키 값 저장소를 삭제하려면 CloudFront [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DeleteKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DeleteKeyValueStore.html) API 작업을 사용하세요.

------

# 키 값 페어의 파일 형식
<a name="kvs-with-functions-create-s3-kvp"></a>

UTF-8 인코딩 파일을 만들 때는 다음 JSON 형식을 사용합니다.

```
{
  "data":[
    {
      "key":"key1",
      "value":"value"
    },
    {
      "key":"key2",
      "value":"value"
    }
  ]
}
```

파일에 중복 키를 포함할 수 없습니다. Amazon S3 버킷에 잘못된 파일을 지정한 경우 파일을 업데이트하여 중복 파일을 제거한 다음 키 값 저장소를 다시 생성해 볼 수 있습니다.

자세한 내용은 [키 값 저장소 생성](kvs-with-functions-create.md) 섹션을 참조하세요.

**참고**  
데이터 소스 및 해당 키-값 페어의 파일에는 다음과 같은 한도가 있습니다.  
파일 크기 - 5MB
키 크기 - 512자
키 크기 - 1,024자

# 키 값 데이터로 작업
<a name="kvs-with-functions-kvp"></a>

이 주제에서는 기존 키 값 저장소에 키 값 페어를 추가하는 방법을 설명합니다. 키 값 저장소를 처음 생성할 때 키 값 페어를 포함하려면 [키 값 저장소 생성](kvs-with-functions-create.md) 섹션을 참조하세요.

**Topics**
+ [

## 키 값 페어 작업(콘솔)
](#kvs-with-functions-kvp-using-console)
+ [

## CloudFront KeyValueStore 소개
](#kvs-with-functions-api-describe)
+ [

## 키 값 페어 작업(AWS CLI)
](#work-with-kvs-cli-keys)
+ [

## 키 값 페어 작업(API)
](#kvs-with-functions-kvp-using-api)

## 키 값 페어 작업(콘솔)
<a name="kvs-with-functions-kvp-using-console"></a>

CloudFront 콘솔을 사용하여 키 값 페어로 작업할 수 있습니다.

**키-값 페어로 작업하려면**

1. AWS Management Console에 로그인하고 [https://console.aws.amazon.com/cloudfront/v4/home#/functions](https://console.aws.amazon.com/cloudfront/v4/home#/functions)에 있는 CloudFront 콘솔에서 **함수** 페이지를 엽니다.

1. **KeyValueStore** 탭을 선택합니다.

1. 변경할 키 값 저장소를 선택합니다.

1. **키 값 페어** 섹션에서 **편집** 버튼을 선택합니다.

1. 키 값 페어를 추가하거나, 키 값 페어를 삭제하거나, 기존 키 값 페어의 값을 변경할 수 있습니다.

1. 작업을 마쳤으면 **변경 내용 저장**을 선택합니다.

## CloudFront KeyValueStore 소개
<a name="kvs-with-functions-api-describe"></a>

**작은 정보**  
CloudFront KeyValueStore API는 인증에 서명 버전 4A(SigV4A)를 사용하는 글로벌 서비스입니다. SigV4A에서 임시 자격 증명을 사용하려면 버전 2 세션 토큰이 필요합니다. 자세한 내용은 [CloudFront KeyValueStore API에 임시 자격 증명 사용](cloudfront-function-restrictions.md#regional-endpoint-for-key-value-store) 섹션을 참조하세요.

AWS Command Line Interface(AWS CLI) 또는 자체 코드를 사용하여 CloudFront KeyValueStore API를 직접 호출하는 경우 다음 섹션을 참조하세요.

키 값 저장소와 해당 키 값 페어를 사용할 때 직접적으로 호출하는 서비스는 사용 사례에 따라 달라집니다.
+ **기존 키 값 저장소에서 키 값 페어를 사용하려면 CloudFront KeyValueStore 서비스를 사용합니다.
+ 키 값 저장소를 처음 생성할 때 키 값 저장소에 키 값 페어를 포함하려면 CloudFront 서비스를 사용합니다.**

CloudFront API와 CloudFront KeyValueStore API에는 모두 `DescribeKeyValueStore` 작업이 있습니다. 직접 호출하는 이유는 여러 가지 입니다. 차이점을 이해하려면 다음 테이블을 참조하세요.


|  | CloudFront DescribeKeyValueStore API | CloudFront KeyValueStore DescribeKeyValueStore API | 
| --- | --- | --- | 
| 키 값 저장소 관련 데이터 |  키 값 저장소 자체가 마지막으로 수정된 상태 및 날짜와 같은 데이터를 반환합니다.  |  스토리지 리소스의 **콘텐츠(저장소의 키 값 페어, 콘텐츠 크기)에 대한 데이터를 제공합니다.  | 
| 키 값 저장소를 식별하는 데이터 |  키 값 저장소의 `ETag`, UUID, ARN을 반환합니다.  |  키 값 저장소의 `ETag`, ARN을 반환합니다.  | 

**참고**  
각 DescribeKeyValueStore 작업은 서로 다른 **`ETag`를 반환합니다. `ETags`는 서로 바꿔서 사용할 수 없습니다.
API 작업을 직접적으로 호출하여 작업을 완료할 때는 적절한 API에서 `ETag`를 지정해야 합니다. 예를 들어 CloudFront KeyValueStore [DeleteKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DeleteKey.html) 작업에서는 CloudFront KeyValueStore [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html) 작업에서 반환한 `ETag`를 지정합니다.
CloudFront KeyValueStore를 사용하여 CloudFront Functions을 호출하는 경우 함수 호출 중에 키 값 저장소의 값이 업데이트되거나 변경되지 않습니다. 업데이트는 함수 호출 사이에 처리됩니다.

## 키 값 페어 작업(AWS CLI)
<a name="work-with-kvs-cli-keys"></a>

CloudFront KeyValueStore에 대해 다음 AWS Command Line Interface 명령을 실행할 수 있습니다.

**Contents**
+ [

### 키 값 페어 나열
](#kvs-cli-list-keys)
+ [

### 키 값 페어 가져오기
](#kvs-cli-get-keys)
+ [

### 키 값 저장소 설명
](#kvs-cli-describe-keys)
+ [

### 키 값 페어 생성
](#kvs-cli-create-keys)
+ [

### 키 값 페어 삭제
](#kvs-cli-delete-keys)
+ [

### 키 값 페어 업데이트
](#kvs-cli-update-key)

### 키 값 페어 나열
<a name="kvs-cli-list-keys"></a>

키 값 저장소의 키 값 페어를 나열하려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore list-keys \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**응답**

```
{
    "Items": [
        {
            "Key": "key1",
            "Value": "value1"
        }
    ]
}
```

### 키 값 페어 가져오기
<a name="kvs-cli-get-keys"></a>

키 값 저장소의 키 값 페어를 가져오려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore get-key \
    --key=key1 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**응답**

```
{
    "Key": "key1",
    "Value": "value1",
    "ItemCount": 1,
    "TotalSizeInBytes": 11
}
```

### 키 값 저장소 설명
<a name="kvs-cli-describe-keys"></a>

키 값 저장소를 설명하려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore describe-key-value-store \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**응답**

```
{
    "ETag": "KV1F83G8C2ARO7P",
    "ItemCount": 1,
    "TotalSizeInBytes": 11,
    "KvsARN": "arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example",
    "Created": "2024-05-08T07:48:45.381000-07:00",
    "LastModified": "2024-08-05T13:50:58.843000-07:00",
    "Status": "READY"
}
```

### 키 값 페어 생성
<a name="kvs-cli-create-keys"></a>

키 값 저장소에 키 값 페어를 생성하려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore put-key \
    --if-match=KV1PA6795UKMFR9 \
    --key=key2 \
    --value=value2 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**응답**

```
{
    "ETag": "KV13V1IB3VIYZZH",
    "ItemCount": 3,
    "TotalSizeInBytes": 31
}
```

### 키 값 페어 삭제
<a name="kvs-cli-delete-keys"></a>

키 값 페어를 삭제하려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore delete-key \
    --if-match=KV13V1IB3VIYZZH \
    --key=key1 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example
```

**출력**

```
{
    "ETag": "KV1VC38T7YXB528",
    "ItemCount": 2,
    "TotalSizeInBytes": 22
}
```

### 키 값 페어 업데이트
<a name="kvs-cli-update-key"></a>

`update-keys` 명령을 사용하여 둘 이상의 키 값 페어를 업데이트할 수 있습니다. 예를 들어 기존 키 값 페어를 삭제하고 다른 키 값 페어를 만들려면 다음 명령을 실행합니다.

```
aws cloudfront-keyvaluestore update-keys \
    --if-match=KV2EUQ1WTGCTBG2 \
    --kvs-arn=arn:aws:cloudfront::123456789012:key-value-store/37435e19-c205-4271-9e5c-example \
    --deletes '[{"Key":"key2"}]' \
    --puts '[{"Key":"key3","Value":"value3"}]'
```

**응답**

```
{
    "ETag": "KV3AEGXETSR30VB",
    "ItemCount": 3,
    "TotalSizeInBytes": 28
}
```

## 키 값 페어 작업(API)
<a name="kvs-with-functions-kvp-using-api"></a>

이 섹션을 따라 프로그래밍 방식으로 키 값 페어 작업 

**Contents**
+ [

### 키 값 저장소에 대한 참조 가져오기
](#kvs-with-functions-api-ref)
+ [

### 키 값 저장소의 키 값 페어 변경
](#kvs-with-functions-api-actions)
+ [

### CloudFront 키 값 저장소 예제 코드
](#example-code-key-value-store)

### 키 값 저장소에 대한 참조 가져오기
<a name="kvs-with-functions-api-ref"></a>

CloudFront KeyValueStore API를 사용하여 쓰기 작업을 직접적으로 호출할 때는 키 값 저장소의 ARN과 `ETag`를 지정해야 합니다. 이 데이터를 가져오려면 다음 작업을 수행합니다.

**키 값 저장소에 대한 참조를 가져오려면**

1. [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ListKeyValueStores.html) API 작업을 사용하여 키 값 저장소 목록을 가져옵니다. 변경할 키 값 저장소를 찾습니다.

1. [CloudFrontKeyValueStore DescribeKeyValueStore API 작업](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DescribeKeyValueStore.html)을 사용하여 이전 단계의 키 값 저장소를 지정합니다.

   응답에는 키 값 저장소의 ARN과 `ETag`가 포함됩니다.
   + 다음 예와 같이 ARN에는 AWS 계정 번호, 상수 `key-value-store`, UUID가 포함됩니다.

     `arn:aws:cloudfront::123456789012:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111`
   + `ETag`는 다음 예와 같습니다.

     `ETVABCEXAMPLE2`

### 키 값 저장소의 키 값 페어 변경
<a name="kvs-with-functions-api-actions"></a>

업데이트하려는 키 값 페어가 들어 있는 키 값 저장소를 지정할 수 있습니다.

다음 CloudFront KeyValueStore API 작업을 참조하세요.
+ [CloudFrontKeyValueStore DeleteKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_DeleteKey.html) – 키 값 페어를 삭제합니다.
+ [CloudFrontKeyValueStore GetKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_GetKey.html) – 키 값 페어를 반환합니다.
+ [CloudFrontKeyValueStore ListKeys](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_ListKeys.html) – 키 값 페어 목록을 반환합니다.
+ [CloudFrontKeyValueStore PutKey](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_PutKey.html) – 다음과 같은 작업을 수행할 수 있습니다.
  + 새 키 이름과 값을 지정하여 하나의 키 값 저장소에 키 값 페어를 생성합니다.
  + 기존 키 이름과 새 키 값을 지정하여 기존 키 값 페어에 다른 값을 설정합니다.
+ [CloudFrontKeyValueStore UpdateKeys](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_kvs_UpdateKeys.html) - 전부 또는 전무 작업 하나로 다음 작업 중 하나 이상을 수행할 수 있습니다.
  + 하나 이상의 키 값 페어 삭제
  + 새 키 값 페어를 하나 이상 생성
  + 하나 이상의 기존 키 값 페어에 다른 값 설정

### CloudFront 키 값 저장소 예제 코드
<a name="example-code-key-value-store"></a>

**Example**  
다음 코드는 키 값 저장소에 대한 `DescribeKeyValueStore` API 작업을 직접적으로 호출하는 방법을 보여줍니다.  

```
const {
  CloudFrontKeyValueStoreClient,
  DescribeKeyValueStoreCommand,
} = require("@aws-sdk/client-cloudfront-keyvaluestore");

require("@aws-sdk/signature-v4-crt");

(async () => {
  try {
    const client = new CloudFrontKeyValueStoreClient({
      region: "us-east-1"
    });
    const input = {
      KvsARN: "arn:aws:cloudfront::123456789012:key-value-store/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
    };
    const command = new DescribeKeyValueStoreCommand(input);

    const response = await client.send(command);
  } catch (e) {
    console.log(e);
  }
})();
```