

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menggunakan AWS SDK untuk Go
<a name="using"></a>

Pelajari cara pemrograman yang umum dan direkomendasikan dengan aplikasi Anda. AWS SDK untuk Go 

**Topics**
+ [Membangun Klien Layanan](#constructing-a-service-client)
+ [Operasi Layanan Panggilan](#calling-service-operations)
+ [Serentak Menggunakan Klien Layanan](#concurrently-using-service-clients)
+ [Menggunakan Operation Paginators](#using-operation-paginators)
+ [Menggunakan Pelayan](#using-waiters)
+ [Menangani Kesalahan dalam SDK](handle-errors.md)

## Membangun Klien Layanan
<a name="constructing-a-service-client"></a>

 Klien layanan dapat dibangun menggunakan `NewFromConfig` fungsi `New` atau yang tersedia dalam paket Go klien layanan. Setiap fungsi akan mengembalikan tipe `Client` struct yang berisi metode untuk menjalankan layanan. APIs Ini `New` dan `NewFromConfig` masing-masing menyediakan serangkaian opsi yang dapat dikonfigurasi yang sama untuk membangun klien layanan, tetapi memberikan pola konstruksi yang sedikit berbeda yang akan kita lihat di bagian berikut. 

### NewFromConfig
<a name="newfromconfig"></a>

 `NewFromConfig`fungsi menyediakan antarmuka yang konsisten untuk membangun klien layanan menggunakan [AWS.config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config). An `aws.Config` dapat dimuat menggunakan [konfigurasi. LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig). Untuk informasi lebih lanjut tentang membangun sebuah`aws.Config`, lihat[Konfigurasikan SDK](configure-gosdk.md). Contoh berikut menunjukkan cara membuat klien layanan Amazon S3 menggunakan dan `aws.Config` `NewFromConfig` fungsi: 

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg)
```

#### Mengesampingkan Konfigurasi
<a name="overriding-configuration"></a>

 `NewFromConfig`dapat mengambil satu atau lebih argumen fungsional yang dapat mengubah `Options` struct konfigurasi klien. Ini memungkinkan Anda untuk membuat penggantian tertentu seperti mengubah Wilayah, atau memodifikasi opsi khusus layanan seperti opsi Amazon S3. `UseAccelerate` Misalnya: 

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg, func(o *s3.Options) {
        o.Region = "us-west-2"
        o.UseAccelerate = true
    })
```

 Penggantian ke `Options` nilai klien ditentukan oleh urutan argumen fungsional yang diberikan. `NewFromConfig` 

### Baru
<a name="new"></a>

**catatan**  
 `New`dianggap sebagai bentuk konstruksi klien yang lebih maju. Kami menyarankan Anda menggunakan `NewFromConfig` untuk konstruksi klien, karena memungkinkan konstruksi menggunakan `aws.Config` struct. Ini menghilangkan kebutuhan untuk membuat instance `Options` struct untuk setiap klien layanan yang dibutuhkan aplikasi Anda. 

 `New`fungsi adalah konstruktor klien menyediakan antarmuka untuk membangun klien hanya menggunakan paket klien `Options` struct untuk mendefinisikan opsi konfigurasi klien. Misalnya, untuk membangun klien Amazon S3 menggunakan: `New` 

```
import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/credentials"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    client := s3.New(s3.Options{
        Region:      "us-west-2",
        Credentials: aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
    })
```

#### Mengesampingkan Konfigurasi
<a name="overriding-configuration-1"></a>

 `New`dapat mengambil satu atau lebih argumen fungsional yang dapat mengubah `Options` struct konfigurasi klien. Ini memungkinkan Anda untuk membuat penggantian tertentu seperti mengubah Wilayah atau memodifikasi opsi khusus layanan seperti opsi Amazon S3. `UseAccelerate` Misalnya: 

```
import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/credentials"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    options := s3.Options{
        Region:      "us-west-2",
        Credentials: aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
    }
    
    client := s3.New(options, func(o *s3.Options) {
        o.Region = "us-east-1"
        o.UseAccelerate = true
    })
```

 Penggantian ke `Options` nilai klien ditentukan oleh urutan argumen fungsional yang diberikan. `New` 

## Operasi Layanan Panggilan
<a name="calling-service-operations"></a>

 Setelah Anda memiliki instance klien layanan, Anda dapat menggunakannya untuk memanggil operasi layanan. Misalnya, untuk memanggil operasi Amazon S3`GetObject`: 

```
response, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        Bucket: aws.String("amzn-s3-demo-bucket"),
        Key:    aws.String("obj-key"),
    })
```

 Saat Anda memanggil operasi layanan, SDK secara sinkron memvalidasi input, membuat serial permintaan, menandatanganinya dengan kredensyal Anda, mengirimkannya ke AWS, dan kemudian melakukan deserialisasi respons atau kesalahan. Dalam kebanyakan kasus, Anda dapat menghubungi operasi layanan secara langsung. Setiap metode klien operasi layanan akan mengembalikan struct respons operasi, dan jenis antarmuka kesalahan. Anda harus selalu memeriksa `error` jenis untuk menentukan apakah terjadi kesalahan sebelum mencoba mengakses struct respons operasi layanan. 

### Melewati Parameter ke Operasi Layanan
<a name="passing-parameters-to-a-service-operation"></a>

 Setiap metode operasi layanan mengambil nilai [context.Context](https://golang.org/pkg/context/#Context) yang dapat digunakan untuk menetapkan tenggat waktu permintaan yang akan dihormati oleh SDK. Selain itu, setiap operasi layanan akan mengambil `<OperationName>Input` struct yang ditemukan di paket Go masing-masing layanan. Anda meneruskan parameter input API menggunakan struct input operasi. 

 Struktur input operasi dapat memiliki parameter input seperti angka Go standar, boolean, string, peta, dan jenis daftar. Dalam operasi API yang lebih kompleks, layanan mungkin memiliki pemodelan parameter input yang lebih kompleks. Jenis lain seperti struktur khusus layanan dan nilai enum ditemukan dalam paket `types` Go layanan. 

 Selain itu, layanan dapat membedakan antara nilai default tipe Go dan apakah nilai ditetapkan atau tidak oleh pengguna. Dalam kasus ini, parameter input mungkin mengharuskan Anda untuk meneruskan referensi pointer ke jenis yang dimaksud. Untuk tipe Go standar seperti numerik, boolean, dan string ada `<Type>` dan fungsi `From<Type>` kenyamanan yang tersedia di [aws](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws) untuk memudahkan konversi ini. Misalnya, [AWS.String](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#String) dapat digunakan untuk mengonversi a `string` ke `*string` tipe untuk parameter input yang memerlukan pointer ke string. Sebaliknya, [aws. ToString](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ToString)dapat digunakan untuk mengubah a `*string` ke a `string` sambil memberikan perlindungan dari dereferensi pointer nil. `To<Type>`Fungsinya sangat membantu saat menangani respons layanan. 

 Mari kita lihat contoh bagaimana kita dapat menggunakan klien Amazon S3 untuk memanggil `GetObject` API, dan membangun input kita menggunakan `types` paket, dan pembantu. `aws.<Type>` 

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    import "github.com/aws/aws-sdk-go-v2/service/s3/types"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg)
    
    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        Bucket:       aws.String("amzn-s3-demo-bucket"),
        Key:          aws.String("keyName"),
        RequestPayer: types.RequestPayerRequester,
    })
```

### Mengganti Opsi Klien Untuk Panggilan Operasi
<a name="overriding-client-options"></a>

 Mirip dengan bagaimana opsi operasi klien dapat dimodifikasi selama konstruksi klien menggunakan argumen fungsional, opsi klien dapat dimodifikasi pada saat metode operasi dipanggil dengan memberikan satu atau lebih argumen fungsional untuk metode operasi layanan. Tindakan ini aman konkurensi dan tidak akan mempengaruhi operasi bersamaan lainnya pada klien. 

 Misalnya, untuk mengganti wilayah klien dari “us-west-2" ke “us-east-1": 

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"))
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    params := &s3.GetObjectInput{
        // ...
    }
    
    resp, err := client.GetObject(context.TODO(), params, func(o *Options) {
        o.Region = "us-east-1"
    })
```

### Menangani Tanggapan Operasi
<a name="handling-operation-responses"></a>

 Setiap operasi layanan memiliki struct keluaran terkait yang berisi anggota respons operasi layanan. Output struct mengikuti pola `<OperationName>Output` penamaan berikut. Beberapa operasi mungkin tidak memiliki anggota yang ditentukan untuk output operasi mereka. Setelah memanggil operasi layanan, tipe `error` argumen pengembalian harus selalu diperiksa untuk menentukan apakah terjadi kesalahan saat menjalankan operasi layanan. Kesalahan yang dikembalikan dapat berkisar dari kesalahan validasi masukan sisi klien hingga respons kesalahan sisi layanan yang dikembalikan ke klien. Struct keluaran operasi tidak boleh diakses jika kesalahan non-nil dikembalikan oleh klien. 

 Misalnya, untuk mencatat kesalahan operasi dan kembali sebelum waktunya dari fungsi panggilan: 

```
response, err := client.GetObject(context.TODO())
    if err != nil {
        log.Printf("GetObject error: %v", err)
        return
    }
```

 Untuk informasi selengkapnya tentang penanganan kesalahan, termasuk cara memeriksa jenis kesalahan tertentu, lihat TODO 

#### Tanggapan dengan `io.ReadCloser`
<a name="responses-with-ioreadcloser"></a>

 Beberapa operasi API mengembalikan struct respons yang berisi anggota keluaran yang merupakan `io.ReadCloser` file. Ini akan menjadi kasus untuk operasi API yang mengekspos beberapa elemen outputnya di badan respons HTTP itu sendiri. 

 Misalnya, `GetObject` operasi Amazon S3 mengembalikan respons yang `Body` anggotanya adalah `io.ReadCloser` untuk mengakses payload objek. 

**Awas**  
 Anda HARUS SELALU `Close()` setiap anggota `io.ReadCloser` output, terlepas dari apakah Anda telah mengkonsumsi kontennya. Kegagalan untuk melakukannya dapat membocorkan sumber daya dan berpotensi menimbulkan masalah dengan membaca badan respons untuk operasi yang disebut di masa depan. 

```
resp, err := s3svc.GetObject(context.TODO(), &s3.GetObjectInput{...})
    if err != nil {
        // handle error
        return
    }
    // Make sure to always close the response Body when finished
    defer resp.Body.Close()
    
    decoder := json.NewDecoder(resp.Body)
    if err := decoder.Decode(&myStruct); err != nil {
        // handle error
        return
    }
```

#### Metadata Respon
<a name="response-metadata"></a>

 Semua struct output operasi layanan termasuk `ResultMetadata` anggota tipe [Middleware.metadata](https://pkg.go.dev/github.com/aws/smithy-go/middleware#Metadata). `middleware.Metadata`digunakan oleh middleware SDK untuk memberikan informasi tambahan dari respons layanan yang tidak dimodelkan oleh layanan. Ini termasuk metadata seperti. `RequestID` Misalnya, untuk mengambil respons `RequestID` terkait dengan layanan untuk membantu AWS Support dalam memecahkan masalah permintaan: 

```
import "fmt"
    import "log"
    import "github.com/aws/aws-sdk-go-v2/aws/middleware"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ..
    
    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        // ...
    })
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    requestID, ok := middleware.GetRequestIDMetadata(resp.ResultMetadata)
    if !ok {
        fmt.Println("RequestID not included with request")
    }
    
    fmt.Printf("RequestID: %s\n", requestID)
```

## Serentak Menggunakan Klien Layanan
<a name="concurrently-using-service-clients"></a>

 Anda dapat membuat goroutine yang secara bersamaan menggunakan klien layanan yang sama untuk mengirim beberapa permintaan. Anda dapat menggunakan klien layanan dengan goroutine sebanyak yang Anda inginkan. 

 Dalam contoh berikut, klien layanan Amazon S3 digunakan di beberapa goroutine. Contoh ini secara bersamaan mengunggah dua objek ke bucket Amazon S3. 

```
import "context"
    import "log"
    import "strings"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    type result struct {
        Output *s3.PutObjectOutput
        Err    error
    }
    
    results := make(chan result, 2)
    
    var wg sync.WaitGroup
    wg.Add(2)
    
    go func() {
    defer wg.Done()
        output, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
            Bucket: aws.String("amzn-s3-demo-bucket"),
            Key:    aws.String("foo"),
            Body:   strings.NewReader("foo body content"),
        })
        results <- result{Output: output, Err: err}
    }()
    
    go func() {
        defer wg.Done()
        output, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
            Bucket: aws.String("amzn-s3-demo-bucket"),
            Key:    aws.String("bar"),
            Body:   strings.NewReader("bar body content"),
        })
        results <- result{Output: output, Err: err}
    }()
    
    wg.Wait()
    
    close(results)
    
    for result := range results {
        if result.Err != nil {
            log.Printf("error: %v", result.Err)
            continue
        }
        fmt.Printf("etag: %v", aws.ToString(result.Output.ETag))
    }
```

## Menggunakan Operation Paginators
<a name="using-operation-paginators"></a>

 Biasanya, saat Anda mengambil daftar item, Anda mungkin perlu memeriksa struct keluaran untuk token atau penanda untuk mengonfirmasi apakah AWS layanan mengembalikan semua hasil dari permintaan Anda. Jika token atau penanda ada, Anda menggunakannya untuk meminta halaman hasil berikutnya. Alih-alih mengelola token atau penanda ini, Anda dapat menggunakan jenis paginator paket layanan yang tersedia. 

 Pembantu paginator tersedia untuk operasi layanan yang didukung, dan dapat ditemukan dalam paket Go klien layanan. Untuk membangun paginator untuk operasi yang didukung, gunakan fungsi. `New<OperationName>Paginator` Fungsi konstruksi paginator mengambil layanan`Client`, parameter `<OperationName>Input` input operasi, dan serangkaian argumen fungsional opsional yang memungkinkan Anda mengonfigurasi pengaturan paginator opsional lainnya. 

 Jenis paginator operasi yang dikembalikan menyediakan cara mudah untuk mengulangi operasi paginasi sampai Anda mencapai halaman terakhir, atau Anda telah menemukan item yang dicari aplikasi Anda. Tipe paginator memiliki dua metode: `HasMorePages` dan. `NextPage` `HasMorePages`mengembalikan nilai boolean `true` jika halaman pertama belum diambil, atau jika halaman tambahan tersedia untuk mengambil menggunakan operasi. Untuk mengambil halaman pertama atau selanjutnya dari operasi, `NextPage` operasi harus dipanggil. `NextPage`mengambil `context.Context` dan mengembalikan output operasi dan kesalahan yang sesuai. Seperti parameter pengembalian metode operasi klien, kesalahan pengembalian harus selalu diperiksa sebelum mencoba menggunakan struktur respons yang dikembalikan. Lihat [Menangani Tanggapan Operasi](#handling-operation-responses). 

 Contoh berikut menggunakan `ListObjectsV2` paginator untuk daftar hingga tiga halaman kunci objek dari operasi. `ListObjectV2` Setiap halaman terdiri dari hingga 10 kunci, yang ditentukan oleh opsi `Limit` paginator. 

```
import "context"
    import "log"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    params := &s3.ListObjectsV2Input{
        Bucket: aws.String("amzn-s3-demo-bucket"),
    }
    
    paginator := s3.NewListObjectsV2Paginator(client, params, func(o *s3.ListObjectsV2PaginatorOptions) {
        o.Limit = 10
    })
    
    pageNum := 0
    for paginator.HasMorePages() && pageNum < 3 {
        output, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Printf("error: %v", err)
            return
        }
        for _, value := range output.Contents {
            fmt.Println(*value.Key)
        }
        pageNum++
    }
```

 Mirip dengan metode operasi klien, opsi klien seperti Region permintaan dapat dimodifikasi dengan memberikan satu atau lebih argumen fungsional untuk`NextPage`. Untuk informasi selengkapnya tentang mengganti opsi klien saat memanggil operasi, lihat[Mengganti Opsi Klien Untuk Panggilan Operasi](#overriding-client-options). 

## Menggunakan Pelayan
<a name="using-waiters"></a>

 Saat berinteraksi dengan AWS APIs yang asinkron, Anda sering harus menunggu sumber daya tertentu tersedia untuk melakukan tindakan lebih lanjut di atasnya. 

 Misalnya, Amazon `CreateTable` DynamoDB API segera kembali dengan TableStatus CREATING, dan Anda tidak dapat menjalankan operasi baca atau tulis hingga status tabel dialihkan. `ACTIVE` 

 Logika penulisan untuk terus melakukan polling status tabel dapat menjadi rumit dan rawan kesalahan. Para pelayan membantu menghilangkan kerumitan dari itu dan sederhana APIs yang menangani tugas pemungutan suara untuk Anda. 

 Misalnya, Anda dapat menggunakan pelayan untuk melakukan polling jika tabel DynamoDB dibuat dan siap untuk operasi tulis. 

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client)
    
    // params is the input to api operation used by the waiter
    params := &dynamodb.DescribeTableInput {
        TableName: aws.String("test-table")
    }
    
    // maxWaitTime is the maximum wait time, the waiter will wait for 
    // the resource status.
    maxWaitTime := 5 * time.Minutes
    
    // Wait will poll until it gets the resource status, or max wait time 
    // expires.
    err := waiter.Wait(context.TODO(), params, maxWaitTime)  
    if err != nil {
        log.Printf("error: %v", err)
        return 
    }
    fmt.Println("Dynamodb table is now ready for write operations")
```

### Mengesampingkan konfigurasi pelayan
<a name="overriding-waiter-configuration"></a>

 Secara default, SDK menggunakan penundaan minimum dan nilai penundaan maksimum yang dikonfigurasi dengan nilai optimal yang ditentukan oleh AWS layanan untuk yang berbeda APIs. Anda dapat mengganti konfigurasi pelayan dengan memberikan opsi fungsional selama konstruksi pelayan, atau saat menjalankan operasi pelayan. 

 Misalnya, untuk mengganti konfigurasi pelayan selama konstruksi pelayan 

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client, func (o *dynamodb.TableExistsWaiterOptions) {
        
        // override minimum delay to 10 seconds
        o.MinDelay = 10 * time.Second
        
        // override maximum default delay to 300 seconds
        o.MaxDelay = 300 * time.Second
    })
```

`Wait`Fungsi pada setiap pelayan juga mengambil opsi fungsional. Mirip dengan contoh di atas, Anda dapat mengganti konfigurasi pelayan per `Wait` permintaan.

```
// params is the input to api operation used by the waiter
    params := &dynamodb.DescribeTableInput {
        TableName: aws.String("test-table")
    }
    
    // maxWaitTime is the maximum wait time, the waiter will wait for 
    // the resource status.
    maxWaitTime := 5 * time.Minutes
    
    // Wait will poll until it gets the resource status, or max wait time 
    // expires.
    err := waiter.Wait(context.TODO(), params, maxWaitTime, func (o *dynamodb.TableExistsWaiterOptions) {
    
        // override minimum delay to 5 seconds
        o.MinDelay = 5 * time.Second
    
        // override maximum default delay to 120 seconds
        o.MaxDelay = 120 * time.Second
    })
    if err != nil {
        log.Printf("error: %v", err)
        return 
    }
    fmt.Println("Dynamodb table is now ready for write operations")
```

### Penggantian konfigurasi pelayan tingkat lanjut
<a name="advanced-waiter-configuration-overrides"></a>

 Anda juga dapat menyesuaikan perilaku default pelayan dengan menyediakan fungsi yang dapat dicoba ulang khusus. Opsi khusus pelayan juga menyediakan `APIOptions` untuk [menyesuaikan](middleware.md#writing-a-custom-middleware) middlewares operasi. 

 Misalnya, untuk mengkonfigurasi penggantian pelayan tingkat lanjut. 

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // custom retryable defines if a waiter state is retryable or a terminal state.
    // For example purposes, we will configure the waiter to not wait 
    // if table status is returned as `UPDATING`
    customRetryable := func(ctx context.Context, params *dynamodb.DescribeTableInput, 
        output *dynamodb.DescribeTableOutput, err error) (bool, error) {
        if output.Table != nil {
            if output.Table.TableStatus == types.TableStatusUpdating {
                // if table status is `UPDATING`, no need to wait
                return false, nil   
            }
        }
    }
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client, func (o *dynamodb.TableExistsWaiterOptions) {
        
        // override the service defined waiter-behavior
        o.Retryable = customRetryable
    })
```