Architecture
openFHIR Engine is a mapping engine. It sits between two components that stay yours:
the FHIR Facade (FHIR server) that receives and serves FHIR requests, and
the openEHR Repository (clinical data repository) that stores Compositions. The engine does not write Compositions to it on your behalf.
Neither of the two is shipped as part of the engine itself, but you do not have to build the glue between them from scratch:
for HAPI FHIR, a ready-made interceptor is available: openfhir-hapi-interceptor,
for Firely Server, a ready-made plugin is available: openfhir-firely-plugin,
for anything else, commercial support can help integrate openFHIR into your stack, or provide a dedicated FHIR API for your specific use case. Get in touch through https://open-fhir.com.
openFHIR Engine exposes RESTful APIs. Through those, you can access namely mapping endpoints you can use when you want to map from FHIR to openEHR or vice-versa.
Where data already moves over a message broker, the engine can alternatively be driven by queues instead of REST calls — see Queue-driven integration below.
FHIR to openEHR
When a request comes in to your FHIR Facade for a creation of a new Resource, your FHIR facade (for example the HAPI interceptor or the Firely Server plugin) should invoke an openFHIR engine to translate the FHIR Resource to an openEHR Composition.
Once you have the openEHR Composition within your FHIR Facade (as a result of the HTTP /openfhir/toopenehr), you should create it against the integrated openEHR Repository. openFHIR Engine does not automatically create it anywhere, so it is in the domain of your FHIR Facade to make a POST towards /ehr/rest/openehr/v1/ehr/{ehrid}/composition according to the openEHR API spec.
openEHR to FHIR
When a search request comes in to your FHIR Facade, your FHIR Facade invokes an openEHR CDR to fetch all relevant Compositions. At this point, openFHIR does not yet offer a translation from FHIR search to an AQL, but is a feature on the roadmap. Once that’s in place, your FHIR Facade invokes an openFHIR Engine to obtain an AQL and sends this AQL to the openEHR Repository.
Compositions returned back are then sent to the openFHIR Engine for a translation to corresponding FHIR Resources.
FHIR Resources returned by the openFHIR Engine represent FHIR counter parts to fetched openEHR Compositions.
Queue-driven integration
Note
Enterprise only, see Queue support.
In the two flows above your component calls openFHIR over REST and waits for the answer. Where FHIR resources or openEHR Compositions are already published to a message broker (Kafka), openFHIR Engine can subscribe to those topics itself, translate every message and publish the result to another topic:
a topic carrying openEHR Compositions (for example the CDR’s change feed) is translated to FHIR Bundles on a topic your FHIR side consumes,
a topic carrying FHIR Bundles is translated to openEHR Compositions on a topic the component that writes to the openEHR Repository consumes,
one topic may carry both; the engine tells them apart per message.
The same mappers, templates and terminology are used as over REST, and the same boundaries apply: openFHIR Engine translates, it does not store. Writing the produced Composition to the openEHR Repository, or the produced Bundle to a FHIR store, stays with the consumer of the target topic. Messages that cannot be translated end up on a dead-letter topic together with the reason.
