Docs / EventSourcingDB / API / run-eventql-query

run-eventql-query

Runs an EventQL query and sends its results.

  • Route: QUERY /api/v2/data/run-eventql-query
  • Category: data
  • Authentication: required, with the API token
  • Answer: a stream of NDJSON

EventQL filters, sorts, groups, and projects the events, across all subjects, into results of any shape you like. A query sees one state of the database throughout: the events up to the latest one at the moment it starts, so events written while it runs are not part of it. The tutorial Running EventQL Queries walks through it step by step.

Request#

The body is a JSON object, with the content type application/json:

Field Type Required Meaning
query string yes The EventQL query to run, such as FROM e IN events PROJECT INTO e.

To list the ID and the type of every event of /books/42:

curl \
  -X QUERY \
  -H "authorization: Bearer secret" \
  -H "content-type: application/json" \
  -d '{"query":"FROM e IN events WHERE e.subject == \"/books/42\" PROJECT INTO { id: e.id, type: e.type }"}' \
  http://localhost:3000/api/v2/data/run-eventql-query

Answer#

The answer is a stream of items, one per line. Each result is a row item:

Type Data When
row value, the result as the PROJECT INTO clause of the query shapes it: any JSON value, null included, or an array for each group of a GROUP BY For every result of the query.
error code, description, and details When the query cannot be run, or fails while it runs, see Errors.
heartbeat empty While nothing else is sent for a while, to keep the connection alive.
end empty Once, as the last item, when the stream ends cleanly.

Heartbeats and the end item work as on every stream of the API, see Streams. A query that finds nothing is answered with the end item alone. An error can follow rows that were sent already, for example when the query divides by zero for one of its events; the rows before it are then only part of the result. A query ends once its client goes away, also while it combines several sources, sorts, groups, or computes STDDEV or VARIANCE in memory, so that it does not go on computing for nobody.

For a database in which /books/42 holds a book-acquired, a book-borrowed, and a book-returned event, the request above is answered with:

{"type":"row","data":{"value":{"id":"0","type":"io.eventsourcingdb.library.book-acquired"}}}
{"type":"row","data":{"value":{"id":"1","type":"io.eventsourcingdb.library.book-borrowed"}}}
{"type":"row","data":{"value":{"id":"2","type":"io.eventsourcingdb.library.book-returned"}}}
{"type":"end","data":{}}

Errors#

The query reports these errors as an error item, followed by the end item:

  • query-missing: The request leaves out the query, or sends an empty string.
  • query-malformed: The query does not parse, which includes a query of nothing but whitespace.
  • query-too-deep: The query nests more than 256 levels, or holds a chain of more than 10,000 operands. This is checked before the query is parsed, so it holds for a query that does not parse as well.
  • query-unevaluable: The query parses, but fails while it runs, such as on a division by zero, possibly after it has sent rows.
  • indexes-rebuilding: The indexes are still being rebuilt after an upgrade, which refuses every query before its results begin.
  • restore-in-progress: A restore is running, which refuses queries until it has finished.
  • file-unreadable: A file of the store that the query needs is damaged, such as an events file whose checksum no longer matches.
  • store-failed: The store refuses reads for good, after a restore that could not empty it again.
  • server-shutting-down: The server began to shut down while the query was running. Before the stream begins, the server answers with 503 instead.

Status Codes#

Before the stream begins, the server answers with a status code other than 200 where it cannot take the request at all, as described in Errors:

  • 400: The content type of the body is not application/json, or the body is no JSON object of the shape above, for example with a field the route does not know, such as options, with a query that is no string, or with null as a value.
  • 401: The API token is missing or wrong.
  • 408: The body did not arrive in time.
  • 413: The body is larger than its limit.
  • 429: Too many requests were sent, or the client already holds 256 open streams, see Rate Limiting; the answer says when to try again.
  • 500: The server failed unexpectedly before the stream began. Once it has begun, the stream breaks off without its end item instead.
  • 503: The server is shutting down.