DynamoDB Lokalny to wersja Amazon DynamoDB, którą można uruchomić lokalnie jako kontener Docker (lub inne formy).
Rozpoczęcie pracy jest bardzo łatwe:
# start container
docker run --rm -p 8000:8000 amazon/dynamodb-local
# connect and create a table
aws dynamodb create-table --endpoint-url http://localhost:8000 --table-name Books --attribute-definitions AttributeName=ISBN,AttributeType=S --key-schema AttributeName=ISBN,KeyType=HASH --billing-mode PAY_PER_REQUEST
# list tables
aws dynamodb list-tables --endpoint-url http://localhost:8000
Więcej na temat
--endpoint-url
wkrótce.
Witam Testcontainers!
To dobry początek. Ale DynamoDB Local jest świetnym rozwiązaniem dla Testcontainers , które “jest frameworkiem typu open source służącym do dostarczania lekkich instancji baz danych, brokerów wiadomości, przeglądarek internetowych lub prawie wszystkiego, co może działać w kontenerze Docker”.
Obsługuje wiele języków (w tym Go!) i baz danych (także infrastrukturę przesyłania wiadomości itp.); Wszystko czego Państwo potrzebują to Docker. Testcontainers for Go ułatwia programowe tworzenie i czyszczenie zależności opartych na kontenerach dla zautomatyzowanych testów integracyjnych/dymnych. Można definiować zależności testowe jako kod, uruchamiać testy i usuwać kontenery po ich zakończeniu.
Testcontainers posiada koncepcję modułów które są “wstępnie skonfigurowane implementacje różnych zależności, które sprawiają, że pisanie testów jest jeszcze łatwiejsze”.
Posiadanie elementu infrastruktury obsługiwanego jako moduł Testcontainer zapewnia płynne działanie typu plug-and-play. To samo dotyczy DynamoDB Local, gdzie moduł Moduł Testcontainers dla DynamoDB Local już jest! Umożliwia on łatwe uruchamianie/testowanie aplikacji DynamoDB opartych na Go lokalnie przy użyciu Dockera.
Pierwsze kroki z modułem Testcontainers dla DynamoDB Local
Super łatwe!
go mod init demo
go get github.com/abhirockzz/dynamodb-local-testcontainers-go
Mogą Państwo skorzystać z przykładowego kodu w sekcji README projektu.
Podsumowując, składa się on z czterech prostych kroków:
- Proszę uruchomić kontener DynamoDB Local Docker,
dynamodblocal.RunContainer(ctx).
- Pobiera uchwyt klienta dla instancji DynamoDB (lokalnej),
dynamodbLocalContainer.GetDynamoDBClient(context.Background()).
- Używa uchwytu klienta do wykonywania operacji. W tym przypadku proszę utworzyć tabelę, dodać element i wysłać zapytanie do tego elementu.
- Kończy działanie na końcu programu (zazwyczaj rejestruje go za pomocą funkcji
defer
),dynamodbLocalContainer.Terminate(ctx).
Opcje modułów
Obsługiwane są następujące parametry konfiguracyjne:
WithTelemetryDisabled
: Po określeniu, DynamoDB local nie będzie wysyłać żadnych danych telemetrycznych.WithSharedDB
: Jeśli użyją Państwo tej opcji, DynamoDB utworzy współdzielony plik bazy danych, w którym przechowywane są dane. Jest to przydatne, jeśli chcą Państwo utrwalać dane, np. między kolejnymi wykonaniami testów.
Aby użyć WithSharedDB
, oto typowy schemat postępowania:
- Proszę uruchomić kontener i uzyskać uchwyt klienta.
- Proszę utworzyć tabelę, dodać dane i wykonać zapytanie.
- Ponowne uruchomienie kontenera
- Proszę zapytać o te same dane (ponownie); powinny tam być.
A oto jak można to zrobić (pominięto obsługę błędów i logowanie):
func withSharedDB() {
ctx := context.Background()
//start container
dynamodbLocalContainer, _ := dynamodblocal.RunContainer(ctx)
defer dynamodbLocalContainer.Terminate(ctx)
//get client
client, _ := dynamodbLocalContainer.GetDynamoDBClient(context.Background())
//create table, add data
createTable(client)
value := "test_value"
addDataToTable(client, value)
//query same data
queryResult, _ := queryItem(client, value)
log.Println("queried data from dynamodb table. result -", queryResult)
//re-start container
dynamodbLocalContainer.Stop(context.Background(), aws.Duration(5*time.Second))
dynamodbLocalContainer.Start(context.Background())
//query same data
client, _ = dynamodbLocalContainer.GetDynamoDBClient(context.Background())
queryResult, _ = queryItem(client, value)
log.Println("queried data from dynamodb table. result -", queryResult)
}
Aby użyć tych opcji razem:
container, err := dynamodblocal.RunContainer(ctx, WithSharedDB(), WithTelemetryDisabled())
The Dokumentacja testcontainers jest całkiem dobra, jeśli chodzi o szczegółowe opisanie sposobu pisania rozszerzenia/modułu. Musiałem jednak poradzić sobie z konkretnym niuansem – związanym z DynamoDB Local.
DynamoDB Endpoint Resolution
W przeciwieństwie do usługi DynamoDB, aby uzyskać dostęp do DynamoDB Local (za pomocą SDK, AWS CLI itp.), należy określić lokalny punkt końcowy – np. http://<your_host>:<service_port>
. Najczęściej jest to właśnie to, czego Państwo używają: http://locahost:8000.
Proces rozwiązywania punktów końcowych zmienił się od czasu AWS SDK for Go v2 – musiałem trochę poszukać, aby to rozgryźć. Mogą Państwo przeczytać w SDK documentation, ale krótka wersja jest taka, że należy określić niestandardowy resolver punktu końcowego. W tym przypadku wystarczy pobrać host i port kontenera docker.
Oto implementacja, jest to również używane w module.
type DynamoDBLocalResolver struct {
hostAndPort string
}
func (r *DynamoDBLocalResolver) ResolveEndpoint(ctx context.Context, params dynamodb.EndpointParameters) (endpoint smithyendpoints.Endpoint, err error) {
return smithyendpoints.Endpoint{
URI: url.URL{Host: r.hostAndPort, Scheme: "http"},
}, nil
}
To była zabawa!
Jak już wspomniałem, Testcontainers ma doskonałą dokumentację, która była pomocna, gdy musiałem owijać głowę wokół tego, jak wspierać, współdzielone flaga (używając WithSharedDB). Rozwiązanie było łatwe (ostatecznie), ale Pojemnik wielokrotnego użytku to właśnie ta sekcja zapaliła mi żarówkę!
Jeśli znajdą Państwo ten projekt interesujący/pomocny, proszę nie wahać się ⭐️ i podzielić się nim z kolegami. Szczęśliwego budowania!