Secondary Use FHIR Server Implementation Guide
0.1.0 - ci-build
Secondary Use FHIR Server Implementation Guide - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
From the repository root, start the synthetic source and privacy adapter with Docker Compose:
mkdir -p secrets
cp config/demo.properties config/instance.properties
: > config/opt-outs.txt
docker compose up --build -d
curl -fsS http://127.0.0.1:8080/health
Open http://127.0.0.1:8080/ for the bundled query UI. The adapter FHIR base is http://127.0.0.1:8080/fhir; the mock source runs inside the container and is not published. These examples use the synthetic demo. For an external hospital source, follow docs/HOSPITAL.md in the repository.
Verkennen creates a criteria-based Group and reads its protected quantity after activation. Export reuses that same Group. The count is the number of people; clinical resource counts come from completed export manifests.
Create /tmp/cohort.json for a synthetic female Crohn cohort. This command can be copied as-is from the repository root:
cat > /tmp/cohort.json <<'JSON'
{
"resourceType": "Group",
"meta": { "profile": ["http://hl7.org/fhir/uv/bulkdata/StructureDefinition/bulk-cohort-group"] },
"modifierExtension": [
{ "url": "http://hl7.org/fhir/uv/bulkdata/StructureDefinition/member-filter", "valueExpression": { "language": "application/x-fhir-query", "expression": "Condition?code=34000006" } },
{ "url": "http://hl7.org/fhir/uv/bulkdata/StructureDefinition/member-filter", "valueExpression": { "language": "application/x-fhir-query", "expression": "Patient?gender=female" } }
],
"type": "person",
"actual": false,
"name": "IBD cohort"
}
JSON
Submit it:
curl -i -fsS \
-H 'Accept: application/fhir+json' \
-H 'Content-Type: application/fhir+json' \
--data-binary @/tmp/cohort.json \
'http://127.0.0.1:8080/fhir/Group'
The adapter returns 201 Created with a stable Group Location. Read that URL, honoring Retry-After while actual=false:
curl -i '{group-location}'
Activation completes when actual=true. Read quantity and the members-refreshed extension; the Group is reused for export. The legacy request with Prefer: respond-async instead returns 202 and an operation-result URL, but the bundled UI uses the direct Group handle.
In external-source mode Group reads exclude members; small quantities are withheld. Update the Group with actual=false and no members to re-evaluate criteria and opt-outs, keeping its id. The membership refresh time is exposed as an extension.
curl -i \
-H 'Accept: application/fhir+json' \
-H 'Prefer: respond-async' \
'http://127.0.0.1:8080/fhir/Group/{group-id}/$export?_type=Observation&_typeFilter=Observation%3Fcode%3Dhttp%3A%2F%2Floinc.org%7C38445-3'
The response is 202 Accepted and includes Content-Location.
curl -fsS '{content-location}'
curl -fsS '{output-url}'
Honor Retry-After while the status is 202. On completion, the first URL returns the Bulk Data manifest as application/json; each output[].url returns FHIR NDJSON. If you add an Accept header to a manifest request, use application/json.
Pseudonymization is automatic. For the smaller analytical representation, add _elements:
curl -i \
-H 'Accept: application/fhir+json' \
-H 'Prefer: respond-async' \
'http://127.0.0.1:8080/fhir/Group/{group-id}/$export?_type=Condition&_elements=Condition.subject,Condition.code'
Partial resources carry the standard SUBSETTED tag.