Skip to content
Registry StackDocsLatest

Configure a FHIR R4 integration

View as Markdown

Use this guide when a reviewed source exposes a bounded FHIR R4 search journey that needs more than one HTTP request. You will keep source authority in configuration, use ordinary Rhai for project-specific decisions, and delegate FHIR search-set parsing to the versioned protocol helper.

Use script when one consultation must follow a bounded relationship or same-origin pagination link. A maintained journey can:

  1. search Patient with reviewed selector parameters;
  2. follow at most the declared number of same-origin pages;
  3. search Coverage using the selected Patient id; and
  4. fetch a related Organization through a reviewed path rule.

This is not a generic FHIR proxy. The script cannot select another origin, credential, HTTP method, unreviewed path, or output field. Transactions, subscriptions, GraphQL, writes, and unbounded pagination remain outside the contract.

You need:

  • a Registry Stack project and reviewed FHIR R4 endpoint;
  • exact Patient selectors and bounded relationship rules;
  • an adapter.rhai file; and
  • synthetic request-aware fixtures for match, no match, and ambiguity.

The starter demonstrates the complete offline sequence before you adapt its endpoint, selectors, relationships, and synthetic observations.

Run these commands in order. The focused test prints a safe synthetic trace. The next command starts the same fixture as a watch smoke; press Ctrl+C after its initial passing report. The final three commands test every fixture, explain the redacted plan, and build the unsigned product inputs.

fhir-r4: FHIR R4

A product-neutral script adapter with bounded FHIR R4 search-set parsing.

registryctl init --from fhir-r4 --project-dir fhir-project
registryctl test --project-dir fhir-project --integration coverage --fixture coverage-active --trace
registryctl test --project-dir fhir-project --integration coverage --fixture coverage-active --watch
registryctl test --project-dir fhir-project
registryctl check --project-dir fhir-project --environment local --explain
registryctl build --project-dir fhir-project --environment local

Generated from the five starter workspaces compiled into registryctl.

The source product and version are optional interoperability evidence. They never select the executor or make Rhai available.

version: 1
id: coverage-active
revision: 1
source:
product: fhir-server
versions: { unverified: [r4-api] }
auth: { type: none }
allow:
- { method: GET, path: /fhir/Patient }
- { method: GET, path: /fhir/Coverage }
- { method: GET, path: /fhir/Organization/* }
input:
birthdate:
role: selector
type: string
format: date
minLength: 10
maxLength: 10
family: { role: selector, type: string, maxLength: 80 }
given: { role: selector, type: string, maxLength: 80 }
capability:
script: { file: adapter.rhai }
outputs:
coverage_status: { type: string, maxLength: 32 }
insurer_name: { type: string, maxLength: 160 }
limits:
calls: 5
source_bytes: 2MiB
deadline: 15s

An exact rule admits only that path. * admits one bounded path segment. A terminal /** is available when a reviewed API genuinely needs a bounded suffix. Query names and values remain script-selected but are independently bounded and canonicalized by the host.

Call the source through the host API, then pass the response to the FHIR helper:

let response = source.get("/fhir/Patient", #{
query: #{
_count: 2,
birthdate: ctx.input.birthdate,
family: ctx.input.family,
given: ctx.input.given
}
});
if response.status != 200 {
return result.fail(failure.source_rejected);
}
let page = protocol.fhir.parse_searchset(response, "Patient");

protocol.fhir.parse_searchset requires a FHIR R4 Bundle whose type is searchset. It returns bounded matches, included, outcomes, and an optional next link. It rejects malformed structure, wrong match resource types, and conflicting next links before the script can use them.

An absolute next link can be passed to source.get only when it has the configured source origin and its path matches an allow rule. Fragments, user information, another port, another scheme, and another host fail before dispatch.

The project script owns profile-specific choices such as identifier systems, Patient matching, Coverage relationships, and the final minimized output map. Keep those decisions visible in the script instead of adding product-specific Rust branches.

The environment supplies the deployment origin and secrets without repeating the auth type:

integrations:
coverage:
source:
origin: https://fhir.internal.invalid
timeout: 10s
concurrency: 4
rate: { per_minute: 120, burst: 10 }

Add private CIDRs, a private CA, mTLS, or a credential binding only when the deployment needs them. These settings cannot widen the stable method and path authority.

Each semantic fixture describes the exact canonical request and its synthetic response. Large FHIR bodies belong under fixtures/bodies/ and are referenced with file. Cover a positive match, no match, ambiguity, and meaningful project-specific variations. The harness derives platform-generic malformed, oversized, timeout, authorization-before-source, and minimization checks.

Terminal window
registryctl test --project-dir <project>
registryctl check \
--project-dir <project> \
--environment <environment> \
--explain

Confirm the request trace contains only reviewed methods and paths, safe header names, bounded query shape, and the expected call order. Fixture success proves the compiled contract and local decoder behavior. It does not prove interoperability, legal suitability, or deployment source semantics.

SymptomCauseFix
source.get rejects a targetThe path or absolute link is outside the reviewed source authority.Correct the script or add the narrow reviewed allow rule.
The FHIR helper rejects a BundleThe response is not one valid R4 search-set shape.Correct the synthetic body or review the real source contract.
The result is ambiguousMore than one subject or relation matched within the bounded journey.Strengthen reviewed selectors or correct the source data.
A later page is not fetchedThe call limit, path rule, same-origin check, or deadline closed the request.Use the smallest honest bounds demonstrated by fixtures.