FHIR Client

Search, translate, and perform explicit custom FHIR operations through the managed script API.

FhirClient is the script-facing API for common FHIR operations. It hides most low-level HAPI FHIR client details while still allowing advanced access through original(). Prefer the managed API whenever it covers the required operation.

Injection and lifecycle use

@InjectFhir
FhirClient fhir

The injected client is available throughout the script lifecycle. FHIR searches are commonly performed in postConvert() to enrich generated resources, but lookups may also be used in preConvert() when HL7 normalization depends on existing FHIR data.

SDK delivery policy

In SDK mode, write behavior can be routed by SDK policy—for example, a Bundle may be written to the local output folder instead of being posted to a FHIR server.

Find by identifier

Identifier patientIdentifier = new Identifier()
  .setSystem("urn:mrn")
  .setValue("12345")

def patientOpt = fhir.findPatientByIdentifier(patientIdentifier)
if (patientOpt.isPresent()) {
  def patient = patientOpt.get()
  LOG.info("Existing Patient: ${patient.idElement.value}")
}

Identifier encounterIdentifier = new Identifier()
  .setSystem("urn:visit-number")
  .setValue("VN-10001")

def encounter = fhir.findEncounterByIdentifier(encounterIdentifier)
  .orElseThrow { new RuntimeException("Encounter not found") }
def resources = fhir.search("Patient", [
  "identifier": "urn:mrn|12345"
])

resources.each { resource ->
  LOG.info(resource.resourceType)
}
def patients = fhir.search()
  .forResource("Patient")
  .where("identifier", "urn:mrn|12345")
  .asList()

Search Bundle and paging

Use searchBundle(...) when you need the raw FHIR search Bundle, selected elements, or paging links. Follow the Bundle next link with searchByUrl(nextUrl).

Bundle page = fhir.searchBundle(
  "Observation",
  ["subject": "Patient/123", "status": "final"],
  50,
  "id", "code", "value", "effective"
)

String nextUrl = page.link
  .find { it.relation == "next" }
  ?.url

if (nextUrl) {
  Bundle nextPage = fhir.searchByUrl(nextUrl)
}

FHIR writes and Bundle delivery

Recommended delivery model

For normal HL7 → FHIR processing, let FireSonic deliver the final Bundle after postConvert(). Use script-side writes only for explicit custom workflows that intentionally perform additional FHIR operations.

// Explicit custom workflow only
Bundle response = fhir.postTransaction(customBundle)

When a script performs an additional FHIR write outside the standard platform delivery path, record the corresponding script-side metric as described in Metrics & Support.

Terminology translation

Use translateCode(...) when only the mapped code is needed. Use translate(...) when the workflow needs the raw FHIR Parameters result.

String loinc = fhir.translateCode(
  "http://local.example/lab-codes",
  "PH_ART",
  "http://loinc.org"
)

if (loinc != null) {
  LOG.info("Mapped code: " + loinc)
}

def resultParameters = fhir.translate(
  "http://local.example/lab-codes",
  "PH_ART",
  "http://loinc.org"
)

Native HAPI access

Advanced access

original() bypasses SDK wrapper behavior and communicates directly with the configured FHIR server. Use it only when the simplified FhirClient API does not cover the required operation.

def hapi = fhir.original()
// Advanced HAPI FHIR operation.
// Prefer FhirClient methods when available.

For the underlying generic client API, see the HAPI FHIR Generic Client documentation.