Run mappings
Note
A whole tutorial referenced here is available in the following Postman collection: https://documenter.getpostman.com/view/1515623/2sBXcLex64
Note
If running against a public sandbox.open-fhir.com, don’t forget to include Authorization header of type Basic.
State of the engine has now been prepared, meaning you can start testing your mappings. Mappings are run through the
FHIR Operations-framework endpoints POST /$tofhir and POST /$toopenehr, as defined by the FHIRconnect REST API
specification.
The example data used throughout this tutorial is a realistic newborn growth chart: a child born on 2022-02-03,
measured daily during the maternity stay (weight in kg, recumbent length and head circumference in cm, BMI in kg/m2).
The FHIR side of the tutorial mappings conforms to the HL7 Vital Signs with Qualifying Elements implementation guide: mapped Observations are coded with the
profile-fixed LOINC codes (29463-7 body weight, 8306-3 body length — the newborn is measured lying down,
39156-5 BMI, 8287-5 head occipital-frontal circumference), carry the mandatory vital-signs category,
status, subject and effective[x], and claim the corresponding IG profile in meta.profile.
openEHR to FHIR
To map from an openEHR Composition to FHIR Resource(s), you need a composition either in a flat format or in a
canonical json format. The $tofhir operation takes a FHIR (R4) Parameters resource as its body, with the
(stringified) composition in a composition parameter:
{
"resourceType": "Parameters",
"parameter": [
{
"name": "composition",
"valueString": "<stringified flat or canonical composition>"
}
]
}
When the composition is flat, the engine cannot deduce the template, so templateId has to be provided (either as a
query parameter, as below, or as an additional templateId parameter in the Parameters body).
The openEHR Composition does not carry the FHIR patient identity, and the Vital Signs profiles require
Observation.subject. The $tofhir operation therefore accepts a patient context parameter (query parameter
below, or part of the nested context parameter in the body) — the engine stamps it as the subject of every
mapped resource that doesn’t get one from the mappings themselves.
- POST http://localhost:8080/$tofhir?templateId=Growth chart&patient=Patient/lina-weber
POST http://localhost:8080/$tofhir?templateId=Growth%20chart&patient=Patient/lina-weber HTTP/1.1 Content-Type: application/fhir+json Body: <Parameters resource wrapping the flat json below>
Alternatively, you can try with a Composition in canonical json format, in which case you do not need to provide a templateId in the request.
- POST http://localhost:8080/$tofhir?patient=Patient/lina-weber
POST http://localhost:8080/$tofhir?patient=Patient/lina-weber HTTP/1.1 Content-Type: application/fhir+json Body: <Parameters resource wrapping the canonical json below>
The response is a FHIR Bundle with the mapped resources, plus an engine-generated Provenance entry describing the
mapping run. When some elements could not be mapped, the Bundle also contains an OperationOutcome entry with
warnings — a partial result can coexist with issues.
FHIR to openEHR
Beauty of the engine is that it is able to run bidirectional mappings, meaning the state we have prepared in a previous
step is used for mapping from FHIR to openEHR and vice versa. To test mapping in the other direction, you can simply
copy-paste output of the step above or use the Bundle provided in the link below (a collection Bundle holding the
Patient and twelve profile-conformant vital-sign Observations). The $toopenehr operation takes the FHIR Bundle
itself as the body (no Parameters wrapper), and returns a Parameters resource with the mapped composition in
the composition parameter’s valueString. The format query parameter selects between canonical
(default) and flat.
- POST http://localhost:8080/$toopenehr?templateId=Growth chart
POST http://localhost:8080/$toopenehr?templateId=Growth%20chart&format=flat HTTP/1.1 Content-Type: application/fhir+json Body: <fhir bundle below>
Note
Feel free to play around with bodies of requests above and see how the mapping engine behaves. In the next step, we’ll be adding a new data point to our existing mapping file.