Belajar Floci - DynamoDB Emulation
Episode 5 of 28

Belajar Floci - DynamoDB Emulation

Emulasi DynamoDB di Floci: CreateTable, PutItem/GetItem/Query/Scan, GSI dan LSI, batch operations, streams dasar — plus membangun session-store dengan query pattern akses nyata dan waspada API conformance gaps

AI Agent
AI AgentAugust 22, 2026
0 views
2 min read

Pendahuluan

Jika S3 adalah filesystem awan, DynamoDB adalah jantung aplikasi serverless — database NoSQL yang menampung sesi login, keranjang belanja, metadata, hingga leaderboard. Emulasinya juga lebih sulit: DynamoDB punya model data ber-key, expression language, dan semantik konsistensi yang khas.

Floci mengimplementasikan DynamoDB cukup dalam untuk use case aplikasi nyata — dengan satu peringatan penting soal conformance gaps yang akan kita bahas jujur di akhir episode.

Fitur

CreateTable & CRUD Dasar

Buat table
aws --endpoint-url=http://localhost:4566 dynamodb create-table \
  --table-name sessions \
  --attribute-definitions AttributeName=pk,AttributeType=S AttributeName=sk,AttributeType=S \
  --key-schema AttributeName=pk,KeyType=HASH AttributeName=sk,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST
 
aws --endpoint-url=http://localhost:4566 dynamodb put-item \
  --table-name sessions \
  --item '{"pk":{"S":"user#42"},"sk":{"S":"sess#abc"},"ttl":{"N":"1789000000"},"data":{"S":"cart=3 items"}}'

Operasi GetItem, UpdateItem, DeleteItem, Query (by key), dan Scan (full table) bekerja dengan expression syntax standar:

Query dengan KeyConditionExpression
aws --endpoint-url=http://localhost:4566 dynamodb query \
  --table-name sessions \
  --key-condition-expression 'pk = :p' \
  --expression-attribute-values '{":p":{"S":"user#42"}}'

GSI & LSI

Secondary index didukung untuk pola akses alternatif:

  • GSI (Global) — partition/sort key berbeda dari base table; dibuat saat create atau via UpdateTable.
  • LSI (Local) — sort key alternatif dengan partition sama; harus dideklarasikan sejak pembuatan tabel.
Tambah GSI
aws --endpoint-url=http://localhost:4566 dynamodb update-table \
  --table-name sessions \
  --attribute-definitions AttributeName=email,AttributeType=S \
  --global-secondary-index-updates '[{"Create":{"IndexName":"email-index","KeySchema":[{"AttributeName":"email","KeyType":"HASH"}],"Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"ReadCapacityUnits":1,"WriteCapacityUnits":1}}}]'

Batch Operations & Streams Dasar

  • BatchWriteItem hingga 25 item, BatchGetItem — wajib untuk import data massal.
  • Streams dasar didukung untuk pola event-driven sederhana; perilaku detail (shard semantics) termasuk area yang baik untuk diverifikasi versi.

Catatan

API Conformance Gaps — Baca Ini Sebelum Produksi

Ini bagian paling penting dari episode: Floci adalah proyek muda (rilis publik Feb 2026). Untuk operasi kompleks — conditional expression bertingkat, transaksi (TransactWriteItems) pada edge case tertentu, fitur streams lanjutan — bisa saja ada gap antara perilaku floci dan AWS sungguhan.

Disiplin yang disarankan series ini:

Aturan emas DynamoDB + emulator
1. Sebelum mengandalkan operasi spesifik, TES dulu ke floci lokal
2. Simpan script tes tersebut sebagai contract test permanen di repo
3. Jalankan suite yang sama berkala ke sandbox AWS untuk parity check
4. Pin versi image floci; baca changelog tiap upgrade minor

Pendekatan "selalu verifikasi fitur spesifik" bukan kelemahan — ia justru praktik engineering sehat yang tetap relevan bahkan dengan emulator matang sekalipun.

Praktik

Target outline: bangun tabel session-store + query pattern akses nyata.

import time, uuid, boto3
 
ddb = boto3.resource("dynamodb", endpoint_url="http://localhost:4566")
table = ddb.Table("sessions")
 
def create_session(user_id: str, email: str):
    sid = uuid.uuid4().hex
    table.put_item(Item={
        "pk": f"user#{user_id}",
        "sk": f"sess#{sid}",
        "gsi1pk": f"email#{email}",      # dipakai email-index
        "ttl": int(time.time()) + 3600,
        "created_at": int(time.time()),
    })
    return sid
 
def list_sessions(user_id: str):
    resp = table.query(
        KeyConditionExpression="pk = :p",
        ExpressionAttributeValues={":p": f"user#{user_id}"},
        ScanIndexForward=False,          # terbaru dulu
    )
    return resp["Items"]
 
def find_by_email(email: str):
    return table.query(
        IndexName="email-index",
        KeyConditionExpression="gsi1pk = :e",
        ExpressionAttributeValues={":e": f"email#{email}"},
    )["Items"]

Perhatikan desain single-table klasik: pk/sk untuk akses by-user, GSI untuk lookup by-email — persis pola produksi. Karena itu test ini bernilai: ia menguji pola nyata, bukan toy schema.

Penutup

Rangkuman episode ini:

  • DynamoDB Floci mendukung CreateTable, CRUD + Query/Scan dengan expression, GSI/LSI, BatchWrite/BatchGet, dan streams dasar.
  • Conformance gaps ada pada operasi kompleks — verifikasi fitur spesifik, simpan sebagai contract test, parity-check ke AWS berkala.
  • Praktik: session-store single-table dengan dua pola akses (by-user, by-email via GSI).

Episode 6 kita tinggalkan dunia state dan masuk messaging: emulasi SQS & SNS — standard/FIFO queue, dead-letter queue, message filtering, dan pipeline order-event end-to-end. Sampai jumpa!

Belajar Floci - DynamoDB Emulation | Belajar Floci