Hey there, fellow Go enthusiast! Ready to dive into the world of DynamoDB? You're in for a treat. We'll be using the github.com/aws/aws-sdk-go-v2/service/dynamodb
package to build a robust API integration. Buckle up, because we're about to make your database interactions smoother than a freshly waxed surfboard.
Before we jump in, make sure you've got:
Let's kick things off by setting up our project:
mkdir dynamodb-go-integration cd dynamodb-go-integration go mod init dynamodb-go-integration go get github.com/aws/aws-sdk-go-v2/service/dynamodb
Time to get our AWS ducks in a row:
import ( "context" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/dynamodb" ) func main() { cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2")) if err != nil { // Handle error } client := dynamodb.NewFromConfig(cfg) }
Let's create a table to play with:
input := &dynamodb.CreateTableInput{ AttributeDefinitions: []types.AttributeDefinition{ { AttributeName: aws.String("ID"), AttributeType: types.ScalarAttributeTypeS, }, }, KeySchema: []types.KeySchemaElement{ { AttributeName: aws.String("ID"), KeyType: types.KeyTypeHash, }, }, TableName: aws.String("MyTable"), ProvisionedThroughput: &types.ProvisionedThroughput{ ReadCapacityUnits: aws.Int64(5), WriteCapacityUnits: aws.Int64(5), }, } _, err = client.CreateTable(context.TODO(), input)
Time to populate our table:
item := map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "1"}, "Name": &types.AttributeValueMemberS{Value: "John Doe"}, } input := &dynamodb.PutItemInput{ Item: item, TableName: aws.String("MyTable"), } _, err = client.PutItem(context.TODO(), input)
Let's fetch some data:
input := &dynamodb.GetItemInput{ Key: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "1"}, }, TableName: aws.String("MyTable"), } result, err := client.GetItem(context.TODO(), input)
Time for a quick update:
input := &dynamodb.UpdateItemInput{ Key: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "1"}, }, TableName: aws.String("MyTable"), UpdateExpression: aws.String("set #n = :n"), ExpressionAttributeNames: map[string]string{ "#n": "Name", }, ExpressionAttributeValues: map[string]types.AttributeValue{ ":n": &types.AttributeValueMemberS{Value: "Jane Doe"}, }, } _, err = client.UpdateItem(context.TODO(), input)
Out with the old:
input := &dynamodb.DeleteItemInput{ Key: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "1"}, }, TableName: aws.String("MyTable"), } _, err = client.DeleteItem(context.TODO(), input)
Let's handle multiple items at once:
input := &dynamodb.BatchWriteItemInput{ RequestItems: map[string][]types.WriteRequest{ "MyTable": { { PutRequest: &types.PutRequest{ Item: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "2"}, "Name": &types.AttributeValueMemberS{Value: "Alice"}, }, }, }, { PutRequest: &types.PutRequest{ Item: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "3"}, "Name": &types.AttributeValueMemberS{Value: "Bob"}, }, }, }, }, }, } _, err = client.BatchWriteItem(context.TODO(), input)
For when you need that extra bit of consistency:
input := &dynamodb.TransactWriteItemsInput{ TransactItems: []types.TransactWriteItem{ { Put: &types.Put{ Item: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "4"}, "Name": &types.AttributeValueMemberS{Value: "Charlie"}, }, TableName: aws.String("MyTable"), }, }, { Update: &types.Update{ Key: map[string]types.AttributeValue{ "ID": &types.AttributeValueMemberS{Value: "2"}, }, TableName: aws.String("MyTable"), UpdateExpression: aws.String("set #n = :n"), ExpressionAttributeNames: map[string]string{ "#n": "Name", }, ExpressionAttributeValues: map[string]types.AttributeValue{ ":n": &types.AttributeValueMemberS{Value: "Alice in Wonderland"}, }, }, }, }, } _, err = client.TransactWriteItems(context.TODO(), input)
Always check for errors and implement retries:
import "github.com/aws/aws-sdk-go-v2/aws/retry" cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"), config.WithRetryer(func() aws.Retryer { return retry.AddWithMaxAttempts(retry.NewStandard(), 5) }), )
For unit tests, use mocks:
type mockDynamoDBClient struct { dynamodbiface.DynamoDBAPI } func (m *mockDynamoDBClient) GetItem(ctx context.Context, params *dynamodb.GetItemInput, optFns ...func(*dynamodb.Options)) (*dynamodb.GetItemOutput, error) { // Return mock data } // Use in your tests client := &mockDynamoDBClient{}
For integration tests, consider using a local DynamoDB instance or a dedicated test environment.
And there you have it! You're now equipped to tackle DynamoDB with Go like a pro. Remember, practice makes perfect, so don't be afraid to experiment and push the boundaries of what you've learned here.
For more in-depth information, check out the AWS SDK for Go V2 Documentation and the DynamoDB Developer Guide.
Now go forth and build some awesome database-driven applications! 🚀