spawn new thread per connection, add yaml for docs and also add GSI to readme
This commit is contained in:
@@ -218,11 +218,11 @@ Scan (full table) | 5000 ops | 234.56 ms | 21320 ops/sec
|
|||||||
- ✅ ProjectionExpression
|
- ✅ ProjectionExpression
|
||||||
- ✅ BatchWriteItem
|
- ✅ BatchWriteItem
|
||||||
- ✅ BatchGetItem
|
- ✅ BatchGetItem
|
||||||
|
- ✅ Global Secondary Indexes
|
||||||
|
|
||||||
### Coming Soon
|
### Coming Soon
|
||||||
|
|
||||||
- ⏳ UpdateItem (works but needs UPDATED_NEW/UPDATED_OLD response filtering to work for full Dynamo Parity)
|
- ⏳ UpdateItem (works but needs UPDATED_NEW/UPDATED_OLD response filtering to work for full Dynamo Parity)
|
||||||
- ⏳ Global Secondary Indexes
|
|
||||||
- ⏳ Local Secondary Indexes
|
- ⏳ Local Secondary Indexes
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|||||||
48
http.odin
48
http.odin
@@ -6,6 +6,7 @@ import vmem "core:mem/virtual"
|
|||||||
import "core:net"
|
import "core:net"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
|
import "core:thread"
|
||||||
|
|
||||||
// HTTP Method enumeration
|
// HTTP Method enumeration
|
||||||
HTTP_Method :: enum {
|
HTTP_Method :: enum {
|
||||||
@@ -100,7 +101,6 @@ response_set_body :: proc(resp: ^HTTP_Response, data: []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Request handler function type
|
// Request handler function type
|
||||||
// Takes context pointer, request, and request-scoped allocator
|
|
||||||
Request_Handler :: #type proc(ctx: rawptr, request: ^HTTP_Request, request_alloc: mem.Allocator) -> HTTP_Response
|
Request_Handler :: #type proc(ctx: rawptr, request: ^HTTP_Request, request_alloc: mem.Allocator) -> HTTP_Response
|
||||||
|
|
||||||
// Server configuration
|
// Server configuration
|
||||||
@@ -122,6 +122,13 @@ default_server_config :: proc() -> Server_Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connection task data - passed to worker threads
|
||||||
|
Connection_Task_Data :: struct {
|
||||||
|
server: ^Server,
|
||||||
|
conn: net.TCP_Socket,
|
||||||
|
source: net.Endpoint,
|
||||||
|
}
|
||||||
|
|
||||||
// Server
|
// Server
|
||||||
Server :: struct {
|
Server :: struct {
|
||||||
allocator: mem.Allocator,
|
allocator: mem.Allocator,
|
||||||
@@ -168,9 +175,9 @@ server_start :: proc(server: ^Server) -> bool {
|
|||||||
server.socket = socket
|
server.socket = socket
|
||||||
server.running = true
|
server.running = true
|
||||||
|
|
||||||
fmt.printfln("HTTP server listening on %v", server.endpoint)
|
fmt.printfln("HTTP server listening on %v (thread-per-connection)", server.endpoint)
|
||||||
|
|
||||||
// Accept loop
|
// Accept loop - spawn a thread for each connection
|
||||||
for server.running {
|
for server.running {
|
||||||
conn, source, accept_err := net.accept_tcp(socket)
|
conn, source, accept_err := net.accept_tcp(socket)
|
||||||
if accept_err != nil {
|
if accept_err != nil {
|
||||||
@@ -180,9 +187,24 @@ server_start :: proc(server: ^Server) -> bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle connection in separate goroutine would go here
|
// Allocate connection data
|
||||||
// For now, handle synchronously (should spawn thread)
|
conn_data := new(Connection_Task_Data, server.allocator)
|
||||||
handle_connection(server, conn, source)
|
conn_data.server = server
|
||||||
|
conn_data.conn = conn
|
||||||
|
conn_data.source = source
|
||||||
|
|
||||||
|
// Spawn a new thread for this connection
|
||||||
|
t := thread.create(connection_worker_thread)
|
||||||
|
if t != nil {
|
||||||
|
t.init_context = context
|
||||||
|
t.data = conn_data
|
||||||
|
thread.start(t)
|
||||||
|
// Thread will clean itself up when done
|
||||||
|
} else {
|
||||||
|
// Failed to create thread, close connection
|
||||||
|
net.close(conn)
|
||||||
|
free(conn_data, server.allocator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -190,12 +212,24 @@ server_start :: proc(server: ^Server) -> bool {
|
|||||||
|
|
||||||
server_stop :: proc(server: ^Server) {
|
server_stop :: proc(server: ^Server) {
|
||||||
server.running = false
|
server.running = false
|
||||||
|
|
||||||
|
// Close listening socket
|
||||||
if sock, ok := server.socket.?; ok {
|
if sock, ok := server.socket.?; ok {
|
||||||
net.close(sock)
|
net.close(sock)
|
||||||
server.socket = nil
|
server.socket = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Worker thread procedure
|
||||||
|
connection_worker_thread :: proc(t: ^thread.Thread) {
|
||||||
|
defer thread.destroy(t) // Clean up thread when done
|
||||||
|
|
||||||
|
conn_data := cast(^Connection_Task_Data)t.data
|
||||||
|
defer free(conn_data, conn_data.server.allocator)
|
||||||
|
|
||||||
|
handle_connection(conn_data.server, conn_data.conn, conn_data.source)
|
||||||
|
}
|
||||||
|
|
||||||
// Handle a single connection
|
// Handle a single connection
|
||||||
handle_connection :: proc(server: ^Server, conn: net.TCP_Socket, source: net.Endpoint) {
|
handle_connection :: proc(server: ^Server, conn: net.TCP_Socket, source: net.Endpoint) {
|
||||||
defer net.close(conn)
|
defer net.close(conn)
|
||||||
@@ -214,7 +248,7 @@ handle_connection :: proc(server: ^Server, conn: net.TCP_Socket, source: net.End
|
|||||||
|
|
||||||
request_alloc := vmem.arena_allocator(&arena)
|
request_alloc := vmem.arena_allocator(&arena)
|
||||||
|
|
||||||
// TODO: Double check if we want *all* downstream allocations to use the request arena?
|
// Set request arena as context allocator for downstream allocations
|
||||||
old := context.allocator
|
old := context.allocator
|
||||||
context.allocator = request_alloc
|
context.allocator = request_alloc
|
||||||
defer context.allocator = old
|
defer context.allocator = old
|
||||||
|
|||||||
884
open_api_doc.yaml
Normal file
884
open_api_doc.yaml
Normal file
@@ -0,0 +1,884 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: JormunDB DynamoDB Wire API
|
||||||
|
version: 0.1.0
|
||||||
|
description: |
|
||||||
|
DynamoDB-compatible JSON-over-HTTP API implemented by JormunDB.
|
||||||
|
Requests are POSTed to a single endpoint (/) and routed by the required `X-Amz-Target` header.
|
||||||
|
servers:
|
||||||
|
- url: http://localhost:8002
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/:
|
||||||
|
post:
|
||||||
|
summary: DynamoDB JSON API endpoint
|
||||||
|
description: |
|
||||||
|
Send DynamoDB JSON protocol requests to this endpoint and set `X-Amz-Target` to the operation name,
|
||||||
|
e.g. `DynamoDB_20120810.GetItem`. The request and response media type is typically
|
||||||
|
`application/x-amz-json-1.0`.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/XAmzTarget'
|
||||||
|
- $ref: '#/components/parameters/XAmzDate'
|
||||||
|
- $ref: '#/components/parameters/Authorization'
|
||||||
|
- $ref: '#/components/parameters/XAmzSecurityToken'
|
||||||
|
- $ref: '#/components/parameters/XAmzContentSha256'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-amz-json-1.0:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/CreateTableRequest'
|
||||||
|
- $ref: '#/components/schemas/DeleteTableRequest'
|
||||||
|
- $ref: '#/components/schemas/DescribeTableRequest'
|
||||||
|
- $ref: '#/components/schemas/ListTablesRequest'
|
||||||
|
- $ref: '#/components/schemas/PutItemRequest'
|
||||||
|
- $ref: '#/components/schemas/GetItemRequest'
|
||||||
|
- $ref: '#/components/schemas/DeleteItemRequest'
|
||||||
|
- $ref: '#/components/schemas/UpdateItemRequest'
|
||||||
|
- $ref: '#/components/schemas/QueryRequest'
|
||||||
|
- $ref: '#/components/schemas/ScanRequest'
|
||||||
|
- $ref: '#/components/schemas/BatchWriteItemRequest'
|
||||||
|
- $ref: '#/components/schemas/BatchGetItemRequest'
|
||||||
|
- $ref: '#/components/schemas/TransactWriteItemsRequest'
|
||||||
|
- $ref: '#/components/schemas/TransactGetItemsRequest'
|
||||||
|
examples:
|
||||||
|
CreateTable:
|
||||||
|
summary: Create a table with a HASH key
|
||||||
|
value:
|
||||||
|
TableName: ExampleTable
|
||||||
|
KeySchema:
|
||||||
|
- AttributeName: pk
|
||||||
|
KeyType: HASH
|
||||||
|
AttributeDefinitions:
|
||||||
|
- AttributeName: pk
|
||||||
|
AttributeType: S
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation response
|
||||||
|
content:
|
||||||
|
application/x-amz-json-1.0:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/CreateTableResponse'
|
||||||
|
- $ref: '#/components/schemas/DeleteTableResponse'
|
||||||
|
- $ref: '#/components/schemas/DescribeTableResponse'
|
||||||
|
- $ref: '#/components/schemas/ListTablesResponse'
|
||||||
|
- $ref: '#/components/schemas/PutItemResponse'
|
||||||
|
- $ref: '#/components/schemas/GetItemResponseUnion'
|
||||||
|
- $ref: '#/components/schemas/DeleteItemResponse'
|
||||||
|
- $ref: '#/components/schemas/UpdateItemResponseUnion'
|
||||||
|
- $ref: '#/components/schemas/QueryResponse'
|
||||||
|
- $ref: '#/components/schemas/ScanResponse'
|
||||||
|
- $ref: '#/components/schemas/BatchWriteItemResponse'
|
||||||
|
- $ref: '#/components/schemas/BatchGetItemResponse'
|
||||||
|
- $ref: '#/components/schemas/TransactWriteItemsResponse'
|
||||||
|
- $ref: '#/components/schemas/TransactGetItemsResponse'
|
||||||
|
'400':
|
||||||
|
description: Client error (ValidationException, SerializationException, etc.)
|
||||||
|
content:
|
||||||
|
application/x-amz-json-1.0:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/DynamoDbError'
|
||||||
|
- $ref: '#/components/schemas/TransactionCanceledException'
|
||||||
|
'500':
|
||||||
|
description: Server error
|
||||||
|
content:
|
||||||
|
application/x-amz-json-1.0:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/DynamoDbError'
|
||||||
|
|
||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
XAmzTarget:
|
||||||
|
name: X-Amz-Target
|
||||||
|
in: header
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
DynamoDB JSON protocol operation selector.
|
||||||
|
JormunDB recognizes targets with the `DynamoDB_20120810.` prefix.
|
||||||
|
Note: `UpdateTable` may be recognized but not implemented.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- DynamoDB_20120810.CreateTable
|
||||||
|
- DynamoDB_20120810.DeleteTable
|
||||||
|
- DynamoDB_20120810.DescribeTable
|
||||||
|
- DynamoDB_20120810.ListTables
|
||||||
|
- DynamoDB_20120810.UpdateTable
|
||||||
|
- DynamoDB_20120810.PutItem
|
||||||
|
- DynamoDB_20120810.GetItem
|
||||||
|
- DynamoDB_20120810.DeleteItem
|
||||||
|
- DynamoDB_20120810.UpdateItem
|
||||||
|
- DynamoDB_20120810.Query
|
||||||
|
- DynamoDB_20120810.Scan
|
||||||
|
- DynamoDB_20120810.BatchGetItem
|
||||||
|
- DynamoDB_20120810.BatchWriteItem
|
||||||
|
- DynamoDB_20120810.TransactGetItems
|
||||||
|
- DynamoDB_20120810.TransactWriteItems
|
||||||
|
example: DynamoDB_20120810.GetItem
|
||||||
|
|
||||||
|
XAmzDate:
|
||||||
|
name: X-Amz-Date
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Optional SigV4 timestamp header (kept for SDK compatibility).
|
||||||
|
|
||||||
|
Authorization:
|
||||||
|
name: Authorization
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Optional SigV4 Authorization header (kept for SDK compatibility).
|
||||||
|
|
||||||
|
XAmzSecurityToken:
|
||||||
|
name: X-Amz-Security-Token
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Optional SigV4 session token header (kept for SDK compatibility).
|
||||||
|
|
||||||
|
XAmzContentSha256:
|
||||||
|
name: X-Amz-Content-Sha256
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Optional SigV4 payload hash header (kept for SDK compatibility).
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
EmptyObject:
|
||||||
|
type: object
|
||||||
|
description: Empty JSON object.
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# AttributeValue & helpers
|
||||||
|
# -------------------------
|
||||||
|
AttributeValue:
|
||||||
|
description: DynamoDB AttributeValue (JSON wire format).
|
||||||
|
type: object
|
||||||
|
minProperties: 1
|
||||||
|
maxProperties: 1
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/AttrS'
|
||||||
|
- $ref: '#/components/schemas/AttrN'
|
||||||
|
- $ref: '#/components/schemas/AttrB'
|
||||||
|
- $ref: '#/components/schemas/AttrBOOL'
|
||||||
|
- $ref: '#/components/schemas/AttrNULL'
|
||||||
|
- $ref: '#/components/schemas/AttrSS'
|
||||||
|
- $ref: '#/components/schemas/AttrNS'
|
||||||
|
- $ref: '#/components/schemas/AttrBS'
|
||||||
|
- $ref: '#/components/schemas/AttrL'
|
||||||
|
- $ref: '#/components/schemas/AttrM'
|
||||||
|
|
||||||
|
AttrS:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [S]
|
||||||
|
properties:
|
||||||
|
S:
|
||||||
|
type: string
|
||||||
|
example: hello
|
||||||
|
|
||||||
|
AttrN:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [N]
|
||||||
|
properties:
|
||||||
|
N:
|
||||||
|
type: string
|
||||||
|
description: Numeric values are encoded as strings in DynamoDB's JSON protocol.
|
||||||
|
example: "42"
|
||||||
|
|
||||||
|
AttrB:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [B]
|
||||||
|
properties:
|
||||||
|
B:
|
||||||
|
type: string
|
||||||
|
description: Base64-encoded binary value.
|
||||||
|
example: AAECAwQ=
|
||||||
|
|
||||||
|
AttrBOOL:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [BOOL]
|
||||||
|
properties:
|
||||||
|
BOOL:
|
||||||
|
type: boolean
|
||||||
|
example: true
|
||||||
|
|
||||||
|
AttrNULL:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [NULL]
|
||||||
|
properties:
|
||||||
|
NULL:
|
||||||
|
type: boolean
|
||||||
|
enum: [true]
|
||||||
|
example: true
|
||||||
|
|
||||||
|
AttrSS:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [SS]
|
||||||
|
properties:
|
||||||
|
SS:
|
||||||
|
type: array
|
||||||
|
items: { type: string }
|
||||||
|
example: [a, b]
|
||||||
|
|
||||||
|
AttrNS:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [NS]
|
||||||
|
properties:
|
||||||
|
NS:
|
||||||
|
type: array
|
||||||
|
description: Numeric set values are encoded as strings.
|
||||||
|
items: { type: string }
|
||||||
|
example: ["1", "2"]
|
||||||
|
|
||||||
|
AttrBS:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [BS]
|
||||||
|
properties:
|
||||||
|
BS:
|
||||||
|
type: array
|
||||||
|
description: Base64-encoded binary set values.
|
||||||
|
items: { type: string }
|
||||||
|
example: [AAE=, AgM=]
|
||||||
|
|
||||||
|
AttrL:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [L]
|
||||||
|
properties:
|
||||||
|
L:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/AttributeValue'
|
||||||
|
|
||||||
|
AttrM:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [M]
|
||||||
|
properties:
|
||||||
|
M:
|
||||||
|
$ref: '#/components/schemas/AttributeMap'
|
||||||
|
|
||||||
|
AttributeMap:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
$ref: '#/components/schemas/AttributeValue'
|
||||||
|
example:
|
||||||
|
pk: { S: "user#1" }
|
||||||
|
sk: { S: "meta" }
|
||||||
|
age: { N: "30" }
|
||||||
|
|
||||||
|
ExpressionAttributeNames:
|
||||||
|
type: object
|
||||||
|
additionalProperties: { type: string }
|
||||||
|
example:
|
||||||
|
"#pk": "pk"
|
||||||
|
|
||||||
|
ExpressionAttributeValues:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
$ref: '#/components/schemas/AttributeValue'
|
||||||
|
example:
|
||||||
|
":v": { S: "user#1" }
|
||||||
|
|
||||||
|
Key:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/AttributeMap'
|
||||||
|
description: Primary key map (HASH, optionally RANGE) encoded as an AttributeMap.
|
||||||
|
|
||||||
|
ReturnValues:
|
||||||
|
type: string
|
||||||
|
description: ReturnValues selector used by UpdateItem.
|
||||||
|
enum: [NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW]
|
||||||
|
example: ALL_NEW
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Table shapes
|
||||||
|
# -------------------------
|
||||||
|
ScalarAttributeType:
|
||||||
|
type: string
|
||||||
|
enum: [S, N, B]
|
||||||
|
example: S
|
||||||
|
|
||||||
|
AttributeDefinition:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [AttributeName, AttributeType]
|
||||||
|
properties:
|
||||||
|
AttributeName: { type: string }
|
||||||
|
AttributeType: { $ref: '#/components/schemas/ScalarAttributeType' }
|
||||||
|
|
||||||
|
KeyType:
|
||||||
|
type: string
|
||||||
|
enum: [HASH, RANGE]
|
||||||
|
example: HASH
|
||||||
|
|
||||||
|
KeySchemaElement:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [AttributeName, KeyType]
|
||||||
|
properties:
|
||||||
|
AttributeName: { type: string }
|
||||||
|
KeyType: { $ref: '#/components/schemas/KeyType' }
|
||||||
|
|
||||||
|
ProjectionType:
|
||||||
|
type: string
|
||||||
|
enum: [KEYS_ONLY, INCLUDE, ALL]
|
||||||
|
example: ALL
|
||||||
|
|
||||||
|
Projection:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [ProjectionType]
|
||||||
|
properties:
|
||||||
|
ProjectionType: { $ref: '#/components/schemas/ProjectionType' }
|
||||||
|
NonKeyAttributes:
|
||||||
|
type: array
|
||||||
|
items: { type: string }
|
||||||
|
|
||||||
|
GlobalSecondaryIndex:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [IndexName, KeySchema, Projection]
|
||||||
|
properties:
|
||||||
|
IndexName: { type: string }
|
||||||
|
KeySchema:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/KeySchemaElement' }
|
||||||
|
minItems: 1
|
||||||
|
Projection: { $ref: '#/components/schemas/Projection' }
|
||||||
|
|
||||||
|
TableStatus:
|
||||||
|
type: string
|
||||||
|
enum: [CREATING, UPDATING, DELETING, ACTIVE, ARCHIVING, ARCHIVED]
|
||||||
|
example: ACTIVE
|
||||||
|
|
||||||
|
TableDescription:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableName, TableStatus]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
TableStatus: { $ref: '#/components/schemas/TableStatus' }
|
||||||
|
CreationDateTime:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: Unix epoch seconds.
|
||||||
|
KeySchema:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/KeySchemaElement' }
|
||||||
|
AttributeDefinitions:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/AttributeDefinition' }
|
||||||
|
GlobalSecondaryIndexes:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/GlobalSecondaryIndex'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
IndexStatus:
|
||||||
|
type: string
|
||||||
|
enum: [ACTIVE]
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Error shapes
|
||||||
|
# -------------------------
|
||||||
|
DynamoDbError:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [__type, message]
|
||||||
|
properties:
|
||||||
|
__type:
|
||||||
|
type: string
|
||||||
|
description: DynamoDB error type identifier.
|
||||||
|
example: com.amazonaws.dynamodb.v20120810#ValidationException
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: Invalid request
|
||||||
|
|
||||||
|
TransactionCanceledException:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [__type, message, CancellationReasons]
|
||||||
|
properties:
|
||||||
|
__type:
|
||||||
|
type: string
|
||||||
|
enum: [com.amazonaws.dynamodb.v20120810#TransactionCanceledException]
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
CancellationReasons:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Code, Message]
|
||||||
|
properties:
|
||||||
|
Code: { type: string, example: ConditionalCheckFailed }
|
||||||
|
Message: { type: string, example: The conditional request failed }
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: CreateTable
|
||||||
|
# -------------------------
|
||||||
|
CreateTableRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, KeySchema, AttributeDefinitions]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
KeySchema:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/KeySchemaElement' }
|
||||||
|
minItems: 1
|
||||||
|
AttributeDefinitions:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/AttributeDefinition' }
|
||||||
|
minItems: 1
|
||||||
|
GlobalSecondaryIndexes:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/GlobalSecondaryIndex' }
|
||||||
|
description: |
|
||||||
|
CreateTable request. JormunDB focuses on TableName, KeySchema, AttributeDefinitions, and optional GSI definitions.
|
||||||
|
|
||||||
|
CreateTableResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableDescription]
|
||||||
|
properties:
|
||||||
|
TableDescription:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableName, TableStatus, CreationDateTime]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
TableStatus: { $ref: '#/components/schemas/TableStatus' }
|
||||||
|
CreationDateTime: { type: integer, format: int64 }
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: DeleteTable / DescribeTable / ListTables
|
||||||
|
# -------------------------
|
||||||
|
DeleteTableRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
|
||||||
|
DeleteTableResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableDescription]
|
||||||
|
properties:
|
||||||
|
TableDescription:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableName, TableStatus]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
TableStatus:
|
||||||
|
type: string
|
||||||
|
enum: [DELETING]
|
||||||
|
|
||||||
|
DescribeTableRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
|
||||||
|
DescribeTableResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Table]
|
||||||
|
properties:
|
||||||
|
Table: { $ref: '#/components/schemas/TableDescription' }
|
||||||
|
|
||||||
|
ListTablesRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
description: ListTables request. JormunDB ignores request fields for this operation.
|
||||||
|
|
||||||
|
ListTablesResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [TableNames]
|
||||||
|
properties:
|
||||||
|
TableNames:
|
||||||
|
type: array
|
||||||
|
items: { type: string }
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: PutItem / GetItem / DeleteItem
|
||||||
|
# -------------------------
|
||||||
|
PutItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Item]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Item: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
PutItemResponse:
|
||||||
|
$ref: '#/components/schemas/EmptyObject'
|
||||||
|
|
||||||
|
GetItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
ProjectionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
|
||||||
|
GetItemResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Item]
|
||||||
|
properties:
|
||||||
|
Item: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
|
||||||
|
GetItemResponseUnion:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/EmptyObject'
|
||||||
|
- $ref: '#/components/schemas/GetItemResponse'
|
||||||
|
|
||||||
|
DeleteItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
DeleteItemResponse:
|
||||||
|
$ref: '#/components/schemas/EmptyObject'
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: UpdateItem
|
||||||
|
# -------------------------
|
||||||
|
UpdateItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key, UpdateExpression]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
UpdateExpression: { type: string }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
ReturnValues: { $ref: '#/components/schemas/ReturnValues' }
|
||||||
|
|
||||||
|
UpdateItemResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Attributes]
|
||||||
|
properties:
|
||||||
|
Attributes: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
|
||||||
|
UpdateItemResponseUnion:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/EmptyObject'
|
||||||
|
- $ref: '#/components/schemas/UpdateItemResponse'
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: Query / Scan
|
||||||
|
# -------------------------
|
||||||
|
QueryRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, KeyConditionExpression]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
IndexName: { type: string }
|
||||||
|
KeyConditionExpression: { type: string }
|
||||||
|
FilterExpression: { type: string }
|
||||||
|
ProjectionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
Limit:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
description: Maximum items to return (default 100 if omitted/0 in JormunDB).
|
||||||
|
ExclusiveStartKey: { $ref: '#/components/schemas/Key' }
|
||||||
|
ScanIndexForward:
|
||||||
|
type: boolean
|
||||||
|
description: Sort order for RANGE key queries (if applicable).
|
||||||
|
|
||||||
|
ScanRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
IndexName: { type: string }
|
||||||
|
FilterExpression: { type: string }
|
||||||
|
ProjectionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
Limit:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
description: Maximum items to return (default 100 if omitted/0 in JormunDB).
|
||||||
|
ExclusiveStartKey: { $ref: '#/components/schemas/Key' }
|
||||||
|
|
||||||
|
ItemsPage:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Items, Count, ScannedCount]
|
||||||
|
properties:
|
||||||
|
Items:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
Count:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ScannedCount:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
LastEvaluatedKey:
|
||||||
|
$ref: '#/components/schemas/Key'
|
||||||
|
|
||||||
|
QueryResponse:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ItemsPage'
|
||||||
|
|
||||||
|
ScanResponse:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/ItemsPage'
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: BatchWriteItem
|
||||||
|
# -------------------------
|
||||||
|
WriteRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
PutRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Item]
|
||||||
|
properties:
|
||||||
|
Item: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
DeleteRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Key]
|
||||||
|
properties:
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
oneOf:
|
||||||
|
- required: [PutRequest]
|
||||||
|
- required: [DeleteRequest]
|
||||||
|
|
||||||
|
BatchWriteItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [RequestItems]
|
||||||
|
properties:
|
||||||
|
RequestItems:
|
||||||
|
type: object
|
||||||
|
description: Map of table name to write requests.
|
||||||
|
additionalProperties:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/WriteRequest' }
|
||||||
|
|
||||||
|
BatchWriteItemResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [UnprocessedItems]
|
||||||
|
properties:
|
||||||
|
UnprocessedItems:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/WriteRequest' }
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: BatchGetItem
|
||||||
|
# -------------------------
|
||||||
|
KeysAndAttributes:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [Keys]
|
||||||
|
properties:
|
||||||
|
Keys:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/Key' }
|
||||||
|
ProjectionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
|
||||||
|
BatchGetItemRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [RequestItems]
|
||||||
|
properties:
|
||||||
|
RequestItems:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
$ref: '#/components/schemas/KeysAndAttributes'
|
||||||
|
|
||||||
|
BatchGetItemResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Responses, UnprocessedKeys]
|
||||||
|
properties:
|
||||||
|
Responses:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
UnprocessedKeys:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
$ref: '#/components/schemas/KeysAndAttributes'
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# API: TransactWriteItems / TransactGetItems
|
||||||
|
# -------------------------
|
||||||
|
TransactWriteItemsRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TransactItems]
|
||||||
|
properties:
|
||||||
|
TransactItems:
|
||||||
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 100
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TransactWriteItem'
|
||||||
|
|
||||||
|
TransactWriteItem:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
oneOf:
|
||||||
|
- required: [Put]
|
||||||
|
- required: [Delete]
|
||||||
|
- required: [Update]
|
||||||
|
- required: [ConditionCheck]
|
||||||
|
properties:
|
||||||
|
Put:
|
||||||
|
$ref: '#/components/schemas/TransactPut'
|
||||||
|
Delete:
|
||||||
|
$ref: '#/components/schemas/TransactDelete'
|
||||||
|
Update:
|
||||||
|
$ref: '#/components/schemas/TransactUpdate'
|
||||||
|
ConditionCheck:
|
||||||
|
$ref: '#/components/schemas/TransactConditionCheck'
|
||||||
|
|
||||||
|
TransactPut:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Item]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Item: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
TransactDelete:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
TransactUpdate:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key, UpdateExpression]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
UpdateExpression: { type: string }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
TransactConditionCheck:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key, ConditionExpression]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
ConditionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
ExpressionAttributeValues: { $ref: '#/components/schemas/ExpressionAttributeValues' }
|
||||||
|
|
||||||
|
TransactWriteItemsResponse:
|
||||||
|
$ref: '#/components/schemas/EmptyObject'
|
||||||
|
|
||||||
|
TransactGetItemsRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TransactItems]
|
||||||
|
properties:
|
||||||
|
TransactItems:
|
||||||
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 100
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Get]
|
||||||
|
properties:
|
||||||
|
Get:
|
||||||
|
$ref: '#/components/schemas/TransactGet'
|
||||||
|
|
||||||
|
TransactGet:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
required: [TableName, Key]
|
||||||
|
properties:
|
||||||
|
TableName: { type: string }
|
||||||
|
Key: { $ref: '#/components/schemas/Key' }
|
||||||
|
ProjectionExpression: { type: string }
|
||||||
|
ExpressionAttributeNames: { $ref: '#/components/schemas/ExpressionAttributeNames' }
|
||||||
|
|
||||||
|
TransactGetItemResult:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/EmptyObject'
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Item]
|
||||||
|
properties:
|
||||||
|
Item: { $ref: '#/components/schemas/AttributeMap' }
|
||||||
|
|
||||||
|
TransactGetItemsResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required: [Responses]
|
||||||
|
properties:
|
||||||
|
Responses:
|
||||||
|
type: array
|
||||||
|
items: { $ref: '#/components/schemas/TransactGetItemResult' }
|
||||||
Reference in New Issue
Block a user