Athena

Quick Start

Run your first Athena gateway and operations calls.

This guide assumes Athena is running at http://localhost:4052.

1. Fetch Rows

curl -X POST "http://localhost:4052/gateway/fetch" \
  -H "content-type: application/json" \
  -H "x-athena-client: athena_logging" \
  -d '{
    "table": "gateway_operation_log",
    "columns": ["id", "client_name", "operation", "created_at"],
    "limit": 10
  }'
use athena_rs::{AthenaClient, BackendType};

let athena = AthenaClient::new_with_backend(
    "http://localhost:4052",
    "gateway_api_key",
    "athena_logging",
    BackendType::Native,
)
.await?;

let rows = athena
    .fetch("gateway_operation_log")
    .columns(["id", "client_name", "operation", "created_at"])
    .limit(10)
    .execute()
    .await?;
import { createClient } from "@xylex-group/athena";

const athena = createClient("http://localhost:4052", "gateway_api_key", {
  client: "athena_logging",
});

const rows = await athena
  .from("gateway_operation_log")
  .select("id,client_name,operation,created_at")
  .limit(10);

2. Execute SQL (client routing)

curl -X POST "http://localhost:4052/query/sql" \
  -H "content-type: application/json" \
  -H "x-athena-client: athena_logging" \
  -d '{
    "driver": "postgresql",
    "query": "select now() as current_time"
  }'
use athena_rs::{AthenaClient, BackendType};

let athena = AthenaClient::new_with_backend(
    "http://localhost:4052",
    "gateway_api_key",
    "athena_logging",
    BackendType::Native,
)
.await?;

let query_result = athena.sql("select now() as current_time").await?;
import { createClient } from "@xylex-group/athena";

const athena = createClient("http://localhost:4052", "gateway_api_key", {
  client: "athena_logging",
});

const queryResult = await athena.query<{ current_time: string }>(
  "select now() as current_time",
);

3. Execute SQL with direct x-pg-uri (PostgreSQL only)

curl -X POST "http://localhost:4052/query/sql" \
  -H "content-type: application/json" \
  -H "x-pg-uri: postgres://app_user:app_password@db.example.com:5432/app_db" \
  -d '{
    "driver": "postgresql",
    "query": "select now() as current_time",
    "db_name": "app_db"
  }'
use reqwest::Client;
use serde_json::json;

let response = Client::new()
    .post("http://localhost:4052/query/sql")
    .header("content-type", "application/json")
    .header(
        "x-pg-uri",
        "postgres://app_user:app_password@db.example.com:5432/app_db",
    )
    .json(&json!({
        "driver": "postgresql",
        "query": "select now() as current_time",
        "db_name": "app_db"
    }))
    .send()
    .await?
    .error_for_status()?;
const response = await fetch("http://localhost:4052/query/sql", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-pg-uri": "postgres://app_user:app_password@db.example.com:5432/app_db",
  },
  body: JSON.stringify({
    driver: "postgresql",
    query: "select now() as current_time",
    db_name: "app_db",
  }),
});

if (!response.ok) throw new Error(await response.text());

For rules, caveats, and route scope, see Direct PostgreSQL Routing (x-pg-uri).

4. Simulate a Pipeline

curl -X POST "http://localhost:4052/pipelines/simulate" \
  -H "content-type: application/json" \
  -H "x-athena-client: athena_logging" \
  -d '{
    "source": {
      "table_name": "gateway_operation_log",
      "limit": 25
    },
    "transform": {
      "group_by": "client_name",
      "aggregation_column": "duration_ms",
      "aggregation_strategy": "avg"
    }
  }'
use reqwest::Client;
use serde_json::json;

let response = Client::new()
    .post("http://localhost:4052/pipelines/simulate")
    .header("content-type", "application/json")
    .header("x-athena-client", "athena_logging")
    .json(&json!({
        "source": {
            "table_name": "gateway_operation_log",
            "limit": 25
        },
        "transform": {
            "group_by": "client_name",
            "aggregation_column": "duration_ms",
            "aggregation_strategy": "avg"
        }
    }))
    .send()
    .await?
    .error_for_status()?;
const response = await fetch("http://localhost:4052/pipelines/simulate", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-athena-client": "athena_logging",
  },
  body: JSON.stringify({
    source: {
      table_name: "gateway_operation_log",
      limit: 25,
    },
    transform: {
      group_by: "client_name",
      aggregation_column: "duration_ms",
      aggregation_strategy: "avg",
    },
  }),
});

if (!response.ok) throw new Error(await response.text());

5. Inspect Cluster Health

curl "http://localhost:4052/health/cluster"
use reqwest::Client;

let response = Client::new()
    .get("http://localhost:4052/health/cluster")
    .send()
    .await?
    .error_for_status()?;
const response = await fetch("http://localhost:4052/health/cluster");
if (!response.ok) throw new Error(await response.text());

6. Download API Contracts

curl "http://localhost:4052/openapi.yaml"
curl "http://localhost:4052/openapi-wss.yaml"
use reqwest::Client;

let http = Client::new();
let openapi = http
    .get("http://localhost:4052/openapi.yaml")
    .send()
    .await?
    .error_for_status()?
    .text()
    .await?;

let openapi_wss = http
    .get("http://localhost:4052/openapi-wss.yaml")
    .send()
    .await?
    .error_for_status()?
    .text()
    .await?;
const openapi = await fetch("http://localhost:4052/openapi.yaml").then((r) => {
  if (!r.ok) throw new Error("Failed to download openapi.yaml");
  return r.text();
});

const openapiWss = await fetch("http://localhost:4052/openapi-wss.yaml").then((r) => {
  if (!r.ok) throw new Error("Failed to download openapi-wss.yaml");
  return r.text();
});

Next Steps