Skip to content
cloudemu
Services

Database

In-memory NoSQL document/key-value store modelled on DynamoDB, Cosmos DB, and Firestore, driven with the real cloud SDKs

aws DynamoDBazr Cosmos DBgcp Firestore

Emulates a managed NoSQL store — the DynamoDB/Cosmos/Firestore table your app writes items to and queries by key. You create a table with a partition key (and optional sort key), then put, get, update, query, and scan schemaless items. Each item is just a map of attributes; the table indexes them by their key so lookups and range queries stay fast.

Reach for it in tests when your code puts an item and reads it back by key, runs a query with a key condition, or scans with a filter — so you can exercise those paths without a real DynamoDB account. For managed relational databases (RDS/Aurora, Azure SQL, Cloud SQL), see Relational Database instead.

ProviderServiceSDK-compatDriver
AWSDynamoDB✓ Liveaws.DynamoDB
AzureCosmos DB✓ Liveazure.CosmosDB
GCPFirestore✓ Livegcp.Firestore

Drive it with the real SDK#

The recommended path is to point the real SDK at the SDK-compat server, so your production data-access code runs unchanged. This creates a table keyed on id and writes one item — the client is the stock AWS SDK, only the endpoint is redirected:

import (
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    "github.com/stackshy/cloudemu/v2"
    awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)

cloud := cloudemu.NewAWS()
ts := httptest.NewServer(awsserver.New(awsserver.Drivers{DynamoDB: cloud.DynamoDB}))

client := dynamodb.NewFromConfig(cfg, func(o *dynamodb.Options) {
    o.BaseEndpoint = aws.String(ts.URL)
})

client.CreateTable(ctx, &dynamodb.CreateTableInput{
    TableName: aws.String("Users"),
    AttributeDefinitions: []types.AttributeDefinition{
        {AttributeName: aws.String("id"), AttributeType: types.ScalarAttributeTypeS},
    },
    KeySchema: []types.KeySchemaElement{
        {AttributeName: aws.String("id"), KeyType: types.KeyTypeHash},
    },
    BillingMode: types.BillingModePayPerRequest,
})

client.PutItem(ctx, &dynamodb.PutItemInput{
    TableName: aws.String("Users"),
    Item: map[string]types.AttributeValue{
        "id":   &types.AttributeValueMemberS{Value: "u1"},
        "name": &types.AttributeValueMemberS{Value: "Alice"},
    },
})

Same shape with azcosmos (Azure) and cloud.google.com/go/firestore (GCP). See the SDK-Compat Server page for the full quick starts.

Call the driver directly#

For in-process setup or assertions you can skip the HTTP hop and call the driver. Items are plain map[string]any, so there's no attribute-value wrapping to deal with:

import dbdriver "github.com/stackshy/cloudemu/v2/services/database/driver"

aws.DynamoDB.CreateTable(ctx, dbdriver.TableConfig{
    Name: "Users", PartitionKey: "id",
})
aws.DynamoDB.PutItem(ctx, "Users", map[string]any{"id": "u1", "name": "Alice"})
item, _ := aws.DynamoDB.GetItem(ctx, "Users", map[string]any{"id": "u1"})

GetItem takes just the key attributes and returns the full item (or nil if absent). Query, Scan, UpdateItem, and batch/transactional writes take the same shape via dbdriver input structs.

Behavior & fidelity#

  • Query and scan paginate. Results come back in a stable key order; pass a Limit and continue with either an offset PageToken or a DynamoDB-style ExclusiveStartKey/LastEvaluatedKey. Queries can also sort descending. Because ordering is stable, page tokens stay valid across calls.
  • Comparisons are numeric-aware. Key conditions and filters order numbers numerically ("10" > "9"), strings lexically, and bools false < true — matching the real services rather than naive string compare.
  • TTL expiry on read. Items whose TTL attribute is past due are treated as absent on the next read, so a Get/Query never returns expired data.
  • Streams / change feed. With streams enabled, PutItem / UpdateItem / DeleteItem emit INSERT / MODIFY / REMOVE records you can read back — useful for testing change-driven pipelines.
  • Global Secondary Indexes. CreateIndex / DescribeIndex / DeleteIndex are supported, and a Query can target a GSI via its IndexName.
  • SDK-compat status — Live. DynamoDB (CreateTable, PutItem, GetItem, UpdateItem, Query, Scan with FilterExpression, Batch*, TransactWriteItems, …), Cosmos DB (databases/containers/documents CRUD + query), and Firestore (:commit, :batchGet, :runQuery, document CRUD) all work through the real SDKs. See SDK-Compat for the full surface.

On this page

On this page