Skip to content

Query API Source Layout

The query API is a read-only LAMBDA
AWS Lambda — processes IoT rule payloads and serves query API logic behind API Gateway.
behind API Gateway
Amazon API Gateway — exposes HTTP routes for latest telemetry and recent events. The browser reads data through API Gateway, not DynamoDB directly.
. It reads from DYNAMODB
Amazon DynamoDB — persists telemetry and event records after Lambda ingest in Phase 2.
via the device_ts_idx GSI — the browser never calls DynamoDB directly.

For curl validation steps, see Query API Validation. For Terraform wiring, see Stack Source Layout.

terraform/modules/lambda_query_api/src/handler.py

lambda_handler(event, context):

  1. Read deviceId from path parameters
  2. Parse route from routeKey or rawPath
  3. Query DynamoDB and return JSON with appropriate HTTP status

Environment variables: TELEMETRY_TABLE_NAME, EVENTS_TABLE_NAME, DEFAULT_EVENTS_LIMIT, MAX_EVENTS_LIMIT.

Method / pathHandler branchSuccessNot found
GET /devices/{deviceId}/telemetry/latesttelemetry_latestHTTP 200 + latest telemetry payloadHTTP 404
GET /devices/{deviceId}/events?limit=Nevents_recentHTTP 200 + events arrayHTTP 404

limit defaults to 10, capped at 50.

Telemetry latest — HTTP 200:

{
"device_id": "esp32-c",
"telemetry": {
"device_id": "esp32-c",
"ts": 1782117400,
"type": "connectivity"
},
"record": {
"device_id": "esp32-c",
"effective_ts": 1782117400,
"payload": {}
}
}

The telemetry object is the device MQTT payload from the payload contract
JSON schema for telemetry (`type=connectivity`) and event (`type=button`, `event=press`) MQTT messages.
.

Recent events — HTTP 200:

{
"device_id": "esp32-c",
"events": [
{
"device_id": "esp32-c",
"ts": 1782117400,
"type": "button",
"event": "press"
}
],
"records": [],
"count": 1,
"limit": 10
}

Unknown device — HTTP 404 with {"error": "No telemetry for device_id=..."} or events equivalent.

Set from Terraform output query_api_invoke_url (no trailing slash required). The dashboard uses the same base as VITE_API_URL.