Bu örnekte, bir DynamoDB örneği oluşturmak için AWS DynamoDB Local docker görüntüsünü kullanacağız, ardından tablo oluşturacağız ve JSON dosyaları kullanarak dolduracağız. Son olarak, NoSQL Workbench kullanarak görselleştireceğiz ve bir öğeyi almak için çok basit bir Go uygulaması yazacağız.


Yapı


├── Makefile
├── fixture.json
├── main.go
├── storage
│   ├── dynamodb.go
│   └── model.go
└── table.json

Dosyalar


Makefile


TABLE=blog
URL=http://localhost:8000

.PHONY: db-up
db-up:
docker run --rm --publish 8000:8000 --name ${TABLE}-dynamodb amazon/dynamodb-local:latest -jar DynamoDBLocal.jar -sharedDb -cors "*"

.PHONY: db-create
db-create:
aws dynamodb --endpoint-url ${URL} create-table --cli-input-json file://table.json || true
aws dynamodb --endpoint-url ${URL} batch-write-item --request-items file://fixture.json

.PHONY: db-show
db-show:
aws dynamodb --endpoint-url ${URL} scan --table-name ${TABLE}

.PHONY: db-del
db-del:
aws dynamodb --endpoint-url ${URL} delete-table --table-name ${TABLE}

table.json


{
"TableName": "blog",
"AttributeDefinitions": [
{
"AttributeName": "_part_key",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "_part_key",
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}

fixture.json


{
"blog": [
{
"PutRequest": {
"Item": {
"_part_key": {
"S": "id#fe622e2a-12f3-40b3-995b-2f28a63c6e42"
},
"_model": {
"S": "user"
},
"id": {
"S": "fe622e2a-12f3-40b3-995b-2f28a63c6e42"
},
"name": {
"S": "Al Pacino"
}
}
}
},
{
"PutRequest": {
"Item": {
"_part_key": {
"S": "id#6f063093-dc46-4864-8fd8-67135e7b5bae"
},
"_model": {
"S": "user"
},
"id": {
"S": "6f063093-dc46-4864-8fd8-67135e7b5bae"
},
"name": {
"S": "Robert De Niro"
}
}
}
}
]
}

main.go


package main

import (
"context"
"fmt"
"log"

"docker/storage"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)

func main() {
ctx := context.Background()

awsConfig, err := config.LoadDefaultConfig(ctx, func(o *config.LoadOptions) error {
o.Region = "eu-west-1"

return nil
})
if err != nil {
log.Fatalln(err)
}

awsDynamo := dynamodb.NewFromConfig(awsConfig, func(o *dynamodb.Options) {
o.BaseEndpoint = aws.String("http://localhost:8000")
})

repository := storage.DynamoDB{
Client: awsDynamo,
Table: "blog",
}

user, err := repository.FindUserByID(ctx, "fe622e2a-12f3-40b3-995b-2f28a63c6e42")
if err != nil {
log.Fatalln(err)
}

fmt.Printf("%+v\n", user)
}

model.go


package storage

type Item struct {
PartKey string `dynamodbav:"_part_key"`
Model string `dynamodbav:"_model"`
}

func (Item) AttrTablePartKey() string {
return "_part_key"
}

type User struct {
Item

ID string `dynamodbav:"id"`
Name string `dynamodbav:"name"`
}

func (u *User) Build() {
u.Item = Item{
PartKey: "id#" + u.ID,
Model: "user",
}
}

dynamodb.go


package storage

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

type DynamoDB struct {
Client *dynamodb.Client
Table string
}

func (d DynamoDB) FindUserByID(ctx context.Context, id string) (User, error) {
model := User{
ID: id,
}
model.Build()

res, err := d.Client.GetItem(ctx, &dynamodb.GetItemInput{
TableName: aws.String(d.Table),
Key: map[string]types.AttributeValue{
model.Item.AttrTablePartKey(): &types.AttributeValueMemberS{Value: model.Item.PartKey},
},
})
if err != nil {
return User{}, fmt.Errorf("get item: %s", err.Error())
}

if res.Item == nil {
return User{}, nil
}

if err := attributevalue.UnmarshalMap(res.Item, &model); err != nil {
return User{}, fmt.Errorf("unmarshal map: %s", err.Error())
}

return model, nil
}

Test


AWS config


$ cat .aws/config
[default]
region = eu-west-1
output = json

$ cat .aws/credentials
[default]
aws_access_key_id = none
aws_secret_access_key = none

Run DynamoDB


$ make db-up

Initializing DynamoDB Local with the following configuration:
Port: 8000
InMemory: false
Version: 2.6.0
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: *

Tabloyu oluştur ve doldur


$ make db-create

NoSQL WorkBench'i yapılandırın


"Add connection" düğmesine tıklayın. "DynamoDB local" sekmesine gidin. Anlamlı bir bağlantı adı verin ve ardından hostname için localhost ve port için 8000 kullanın.


Go servisini çalıştırın


$ go run -race main.go
{Item:{TablePartKey:id#fe622e2a-12f3-40b3-995b-2f28a63c6e42 Model:user} ID:fe622e2a-12f3-40b3-995b-2f28a63c6e42 Name:Al Pacino}