Initial Release
FHIRQL Gateway is a Rust-first, portable SQL-like query and execution runtime
for FHIR REST APIs.
Canonical JSON plans under examples/plans are the stable execution contract.
User-facing .fhirql text is parsed into those canonical plans before
validation, planning, and execution. The benchmark materials under
examples/benchmark and tests/fixtures/performance are regression fixtures
and acceptance coverage, not a separate runtime.
The supported canonical plan shape is documented in
docs/CANONICAL_PLAN.md.
Format:
cargo fmt --all
cargo fmt --all -- --check
Lint:
cargo clippy --workspace --all-targets -- -D warnings
Test:
cargo test --workspace
Optional IRIS-backed FHIR integration tests live under
integration_tests/iris. They use Python only to orchestrate either an
existing IRIS FHIR endpoint or a testcontainers-iris container; execution
still goes through the Rust CLI.
python3 -m venv .venv-iris
. .venv-iris/bin/activate
python -m pip install -r integration_tests/iris/requirements.txt
FHIRQL_RUN_IRIS_INTEGRATION=1 python -m pytest integration_tests/iris
Validate a canonical JSON FHIRQL plan:
cargo run -p fhirql-cli -- validate examples/plans/worsening_hba1c.json
Execute against embedded mock FHIR fixtures:
cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json --mock
Parse a FHIRQL text query into the canonical JSON plan shape:
cargo run -p fhirql-cli -- parse examples/benchmark/queries/01_patient_timeline.fhirql
Execute a FHIRQL text query through the same backend options:
cargo run -p fhirql-cli -- execute-text examples/benchmark/queries/02_worsening_hba1c_on_insulin.fhirql --mock --today 2026-05-23
For deterministic runs with a fixed runtime date:
cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json --mock --today 2026-05-23
The mock backend uses the shared synthetic fixture pack in
fhirql-test-data/tests/fixtures/fhir.
The larger 10k benchmark pack is copied into tests/fixtures/performance with
benchmark text queries, canonical example plans, and expected results under
examples/benchmark.
Run the accepted benchmark scenarios directly through the CLI:
cargo run -p fhirql-cli -- benchmark all
Or run one scenario with the short query id:
cargo run -p fhirql-cli -- benchmark ckd_egfr_decline --today 2026-05-23
Supported benchmark ids are 01_patient_timeline,
02_worsening_hba1c_on_insulin, 03_asthma_night_symptoms_semantic,
04_uncontrolled_hypertension_despite_medication,
05_ckd_egfr_decline, 06_abnormal_hba1c_no_followup,
07_anticoagulant_nsaid_overlap, 08_copd_recurrent_exacerbations,
and 09_chf_weight_gain. Short names such as patient_timeline,
abnormal_hba1c_no_followup, and chf_weight_gain are accepted too.
Execute against a standard FHIR R4 REST server:
cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json --fhir-base-url http://localhost:8080/fhir/r4
For local IRIS development with Basic Auth:
cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json \
--fhir-base-url http://localhost:8080/fhir/r4 \
--basic-user _system \
--basic-password SYS
Inspect backend capabilities:
cargo run -p fhirql-cli -- capabilities \
--fhir-base-url http://localhost:8080/fhir/r4 \
--basic-user _system \
--basic-password SYS
For a compact FHIRQL-oriented capability view:
cargo run -p fhirql-cli -- capabilities --summary \
--fhir-base-url http://localhost:8080/fhir/r4 \
--basic-user _system \
--basic-password SYS
Load the shared synthetic fixtures into a local FHIR server:
cargo run -p fhirql-cli -- load-fixtures \
fhirql-test-data/tests/fixtures/fhir/all-resources-transaction-bundle.json \
--fhir-base-url http://localhost:8080/fhir/r4 \
--basic-user _system \
--basic-password SYS
You can also provide the REST backend through environment variables:
FHIR_BASE_URL=http://localhost:8080/fhir/r4 cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json
FHIR_BASE_URL=http://localhost:8080/fhir/r4 \
FHIR_BASIC_USER=_system \
FHIR_BASIC_PASSWORD=SYS \
cargo run -p fhirql-cli -- execute examples/plans/worsening_hba1c.json
Build the local image:
docker build -t fhirql-gateway:local .
The image contains the fhirql, fhirql-mcp, and fhirql-pgwire binaries.
Its default entrypoint is PGWire, bound to 0.0.0.0:55432 for container use:
docker run --rm -p 55432:55432 fhirql-gateway:local
Append PGWire flags directly. For example, run against the packaged benchmark
JSON fixtures:
docker run --rm -p 55432:55432 fhirql-gateway:local --benchmark-fixtures
Or point PGWire at a live FHIR REST endpoint:
docker run --rm -p 55432:55432 \
-e FHIR_BASE_URL=http://host.docker.internal:8080/fhir/r4 \
fhirql-gateway:local \
--auth cleartext \
--user fhirql \
--password fhirql
Other tools are available by overriding the entrypoint:
docker run --rm --entrypoint fhirql fhirql-gateway:local --help
docker run --rm -i --entrypoint fhirql-mcp fhirql-gateway:local --mock
The PGWire gateway is a limited DBeaver-compatible FHIRQL surface. It supports
safe PostgreSQL metadata probes plus native FHIRQL ... text parsing for the
canonical FHIRQL subset. It is not a full PostgreSQL server or a general SQL
engine.
Start it:
cargo run -p fhirql-pgwire -- --port 55432
psql -h localhost -p 55432 -d fhirql
To run the benchmark .fhirql examples locally through DBeaver or psql, start
PGWire with the benchmark fixtures:
cargo run -p fhirql-pgwire -- --port 55432 --benchmark-fixtures
You can also point at any compatible local fixture directory:
cargo run -p fhirql-pgwire -- --port 55432 --fixture-dir tests/fixtures/performance/json
Then run:
SELECT version();
FHIRQL FROM Patient p WHERE EXISTS Condition diabetes ON diabetes.subject = p WHERE diabetes.code IN @diabetes RETURN patient, evidence LIMIT 10;
Supported native text includes the benchmark/demo shapes for:
DocumentReference matchBenchmark query text such as 01_patient_timeline.fhirql through
09_chf_weight_gain.fhirql is parsed to canonical Rust plans before execution.
PGWire requires the FHIRQL prefix, including for SQL-style text such as
FHIRQL SELECT patient FROM Patient p WHERE p.id = 'Patient/p-00001'.
Canonical JSON plans remain the stable runtime contract.
The DBeaver result columns are:
patient_idpatient_displayresult_jsonevidence_jsonrow_indexstatuswarnings_jsonmetadata_jsonFor DBeaver, use cleartext password authentication:
cargo run -p fhirql-pgwire -- --port 55432 --auth cleartext --user fhirql --password fhirql
To execute native FHIRQL from DBeaver against a live FHIR REST server, start
PGWire with a REST backend:
cargo run -p fhirql-pgwire -- \
--port 55432 \
--auth cleartext \
--user fhirql \
--password fhirql \
--fhir-base-url http://localhost:8080/fhir/r4 \
--fhir-basic-user _system \
--fhir-basic-password SYS
DBeaver connection settings:
localhost55432fhirqlfhirqlfhirqlThe MCP server is a thin tools-only adapter over the Rust-owned canonical plan
API. Backend details are fixed at server startup; MCP tool calls cannot supply
arbitrary FHIR URLs or credentials.
Run against deterministic mock fixtures:
cargo run -p fhirql-mcp -- --mock --today 2026-05-23
Run against a standard FHIR REST backend:
cargo run -p fhirql-mcp -- \
--fhir-base-url http://localhost:8080/fhir/r4 \
--basic-user _system \
--basic-password SYS \
--today 2026-05-23
Exposed MCP tools:
fhirql_validate_planfhirql_compile_planfhirql_execute_planfhirql_backend_capabilitiesfhirql_explain_result