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

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.
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:
aws --endpoint-url=http://localhost:4566 dynamodb query \
--table-name sessions \
--key-condition-expression 'pk = :p' \
--expression-attribute-values '{":p":{"S":"user#42"}}'Secondary index didukung untuk pola akses alternatif:
UpdateTable.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}}}]'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:
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 minorPendekatan "selalu verifikasi fitur spesifik" bukan kelemahan — ia justru praktik engineering sehat yang tetap relevan bahkan dengan emulator matang sekalipun.
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.
Rangkuman episode ini:
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!