Documentation
Learning material for the six database ports. The specification decides what must be true; these pages explain how it works and how to use it.
The repository's other two families are documented elsewhere: the model crate in
fhir/, the HTTP surface in
fhir-store/. spec/index.md
routes between all three.
Tutorials#
Read in order the first time; each builds on the last.
- Your first store — install a schema, write a resource, read it back, search for it. About 15 minutes, no server required.
- The storage model — what a resource
becomes: base tables, child tables,
ords, choices, references, extensions. - Querying with SQL — treat it as the relational schema it is. Joins, aggregates, and the idioms that differ per engine.
- FHIR search — search parameters, modifiers, paging, and why "aero" finds "Ærø".
- History and audit — versions, attribution, the tamper-evident chain, keys, and erasure.
- Porting to a new database — what changes, what must not, and the order to do it in.
Reference#
- Choosing an engine — the six ports compared: status, type bindings, what each costs you.
- The storage model — the conceptual reference behind tutorial 2, for looking things up rather than reading through.
- The trust boundary — what these libraries guarantee
about PHI, and what your deployment must provide. One table, per
PR12.8. - Examples — short recipes: bulk load, conditional create, chain verification, cross-version stores, integrity reports.
- FAQ — why not JSONB, why so many tables, is it FHIR-compliant, can I use it in production.
Status, before you rely on anything#
- Conformance matrix — what each port
satisfies, requirement by requirement. Four of the six ports have
?against the concurrency and audit guarantees, which means the code is shared from a port where they are tested and nothing tests them there. - Audit findings — every known divergence between spec, docs, and code, with evidence.
The per-port README.md files were rewritten on 2026-07-31 and should now agree
with the matrix — all six had carried the PostgreSQL reference's measured
results with the engine name substituted, and documented a CLI existing in no
workspace (F-01). If a README and the matrix disagree, the README is the
defect.
The per-port book/ directories have not been rewritten and still contain
PostgreSQL text and REST chapters for a service that does not exist.
Which engine does the examples use#
Most examples use fhir-sqlite, because it needs no server and its code is
short enough to read. The API shape is the same across ports:
| SQLite | PostgreSQL | |
|---|---|---|
| Open | SqliteStore::open(path, map) |
Store::connect(cfg, map) |
| Install | store.init(checksum) |
store.init(checksum) |
| Write | store.put(&json, &audit) |
store.put(&json) / put_audited |
| Read | store.get(rtype, id) |
store.get(rtype, id) |
| Search | store.search(rtype, ¶ms, count, offset) |
same |
Where a port differs materially, the page says so.
Conventions in these pages#
- Code is Rust against the crates as they exist, and
scripts/check-doc-examples.shcompiles every one of them (F-60). If an example does not compile, that is a bug in the page (W16.9). No example here describes a CLI, because none exists; the REST server does exist, as the separate cratefhir-loco, and these pages are about the storage libraries rather than about it. - Requirement ids appear inline —
(M3.4a)— so you can get from an explanation to the decision behind it. - Limitations are stated next to capabilities, not in a footnote.