

# DAX SDK for Go
<a name="DAX.client.run-application-go-2"></a>

다음 절차에 따라 Amazon EC2 인스턴스에서 Amazon DynamoDB Accelerator(DAX) SDK for Go 샘플 애플리케이션을 실행합니다.

**DAX용 SDK for Go 샘플을 실행하려면**

1. Amazon EC2 인스턴스에 SDK for Go를 설치합니다.

   1. Go 프로그래밍 언어(`Golang`)를 설치합니다.

      ```
      sudo yum install -y golang
      ```

   1. Golang가 설치되었고 올바르게 실행되는지 테스트합니다.

      ```
      go version
      ```

      다음과 같은 메시지가 나타납니다.

      ```
      go version go1.23.4 linux/amd64
      ```

1. 샘플 Golang 애플리케이션을 설치합니다.

   ```
   go get github.com/aws-samples/sample-aws-dax-go-v2
   ```

1. 다음 Golang 프로그램을 실행합니다. 첫 프로그램은 `TryDaxGoTable`이라는 DynamoDB 테이블을 생성합니다. 두 번째 프로그램은 해당 테이블에 데이터를 씁니다.

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command create-table
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command put-item
   ```

1. 다음 Golang 프로그램을 실행합니다.

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command get-item
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command query
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command scan
   ```

   `GetItem`, `Query` 및 `Scan` 테스트에 필요한 시간 정보(밀리초)를 기록해 둡니다.

1. 전 단계에서 DynamoDB 엔드포인트에 대해 프로그램을 실행했습니다. 이제 프로그램을 다시 실행하되, 이번에는 `GetItem`, `Query` 및 `Scan` 작업을 DAX 클러스터에서 처리합니다.

   DAX 클러스터의 엔드포인트를 정의하려면 다음 중 하나를 선택합니다.
   + **Using the DynamoDB console(DynamoDB 콘솔 사용)** - DAX 클러스터를 선택합니다. 다음 예제와 같이 클러스터 엔드포인트가 콘솔에 표시됩니다.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **AWS CLI 사용** - 다음 명령을 입력합니다.

     ```
     aws dax describe-clusters --query "Clusters[*].ClusterDiscoveryEndpoint"
     ```

     다음 예제와 같이 클러스터 엔드포인트가 출력에 표시됩니다.

     ```
     {
         "Address": "my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com",
         "Port": 8111,
         "URL": "dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com"
     }
     ```

   이제 프로그램을 다시 실행합니다. 이번에는 클러스터 엔드포인트를 명령줄 파라미터로 지정합니다.

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command get-item -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command query -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command scan -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-scan -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-query -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-batch-get -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   나머지 출력을 확인하여 시간 정보를 기록해 둡니다. `GetItem`, `Query`, `Scan`에 대한 경과 시간은 DAX가 DynamoDB보다 현저히 적어야 합니다.

1. 다음 Golang 프로그램을 실행하여 `TryDaxGoTable`을 삭제합니다.

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command delete-table
   ```

## AWS SDK for Go SDK V2와 동등하지 않은 기능
<a name="DAX.client.run-application-go-features-not-in-parity"></a>

미들웨어 스택 - DAX Go V2는 APIoptions를 통한 미들웨어 스택 사용을 지원하지 않습니다. 자세한 내용은 [Customizing the AWS SDK for Go v2 Client Requests with Middleware](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/middleware.html#:~:text=You%20can%20customize%20AWS%20SDK,step's%20input%20and%20output%20types)를 참조하세요.

예제:

```
// Custom middleware implementation
type customSerializeMiddleware struct{}
// ID returns the identifier for the middleware
func (m *customSerializeMiddleware) ID() string {
    return "CustomMiddleware"
}
// HandleSerialize implements the serialize middleware handler
func (m *customSerializeMiddleware) HandleSerialize(
    ctx context.Context,
    in middleware.SerializeInput,
    next middleware.SerializeHandler,
) (
    out middleware.SerializeOutput,
    metadata middleware.Metadata,
    err error,
) {
    // Add your custom logic here before the request is serialized
    fmt.Printf("Executing custom middleware for request: %v\n", in)
    // Call the next handler in the middleware chain
    return next.HandleSerialize(ctx, in)
}

func executeGetItem(ctx context.Context) error {
    client, err := initItemClient(ctx)
    if err != nil {
        os.Stderr.WriteString(fmt.Sprintf("failed to initialize client: %v\n", err))
        return err
    }

    st := time.Now()
    for c := 0; c < iterations; c++ {
        for i := 0; i < pkMax; i++ {
            for j := 0; j < skMax; j++ {
                // Create key using attributevalue.Marshal for type safety
                pk, err := attributevalue.Marshal(fmt.Sprintf("%s_%d", keyPrefix, i))
                if err != nil {
                    return fmt.Errorf("error marshaling pk: %v", err)
                }
                sk, err := attributevalue.Marshal(fmt.Sprintf("%d", j))
                if err != nil {
                    return fmt.Errorf("error marshaling sk: %v", err)
                }
                key := map[string]types.AttributeValue{
                    "pk": pk,
                    "sk": sk,
                }
                in := &dynamodb.GetItemInput{
                    TableName: aws.String(table),
                    Key:       key,
                }

                // Custom middleware option
                customMiddleware := func(o *dynamodb.Options) {
                    o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
                        // Add custom middleware to the stack
                        return stack.Serialize.Add(&customSerializeMiddleware{}, middleware.After)
                    })
                }

                // Apply options to the GetItem call
                out, err := client.GetItem(ctx, in, customMiddleware)
                if err != nil {
                    return err
                }
                writeVerbose(out)
            }
        }
    }
    d := time.Since(st)
    os.Stdout.WriteString(fmt.Sprintf("Total Time: %v, Avg Time: %v\n", d, d/iterations))
    return nil
}
```

출력:

```
failed to execute command: custom middleware through APIOptions is not supported in DAX client
exit status 1
```