https://github.com/miracum/fhir-gateway
A thin layer between FHIR REST clients and resource processing pipelines.
https://github.com/miracum/fhir-gateway
fhir fhir-api fhir-server kafka
Last synced: 5 months ago
JSON representation
A thin layer between FHIR REST clients and resource processing pipelines.
- Host: GitHub
- URL: https://github.com/miracum/fhir-gateway
- Owner: miracum
- License: apache-2.0
- Created: 2020-04-15T08:39:31.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2026-01-10T12:48:33.000Z (5 months ago)
- Last Synced: 2026-01-10T22:22:29.370Z (5 months ago)
- Topics: fhir, fhir-api, fhir-server, kafka
- Language: Java
- Homepage:
- Size: 2.77 MB
- Stars: 14
- Watchers: 0
- Forks: 7
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# FHIR Gateway

[](https://scorecard.dev/viewer/?uri=github.com/miracum/fhir-gateway)
[](https://slsa.dev)
A thin layer between FHIR REST clients and resource processing pipelines.
## Overview

## Run it
The recommended deployment is on Kubernetes. See for
a Helm Chart.
An example for deploying using (Docker) Compose can be found in the [deploy folder](./deploy/README.md).
Also see the now archived for an example end-to-end deployment.
## Configuration
To configure your deployment, you can change the following environment variables:
| Variable | Description | Default |
|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|
| SPRING_DATASOURCE_URL | JDBC URL of the Postgres DB to store the received FHIR resources, needs to be set to an empty variable if no PSQL db is to be connected to | jdbc:postgresql://fhir-db:5432/fhir |
| SPRING_DATASOURCE_USERNAME | Username of the Postgres DB | postgres |
| SPRING_DATASOURCE_PASSWORD | Password for the Postgres DB | postgres |
| SERVICES_LOINC_CONVERSIONS_ENABLED | Wether LOINC harmonization should be enabled | false |
| SERVICES_LOINC_CONVERSIONS_URL | URL of the [LOINC conversion service](https://github.com/miracum/loinc-conversion) | |
| SERVICES_PSEUDONYMIZER_ENABLED | Whether pseudonymization should be enabled. | false |
| SERVICES_PSEUDONYMIZER_URL | URL of the [FHIR Pseudonymizer service](https://github.com/miracum/fhir-pseudonymizer) | |
| SERVICES_FHIRSERVER_ENABLED | Wether storing resources in a downstream FHIR Server should be enabled | false |
| SERVICES_FHIRSERVER_URL | URL of the FHIR server to send data to | |
| SERVICES_FHIRSERVER_AUTH_BASIC_ENABLED | Enable HTTP basic auth for sending data to FHIR server | false |
| SERVICES_FHIRSERVER_AUTH_BASIC_USERNAME | HTTP basic auth username of the FHIR server to send data to | `""` |
| SERVICES_FHIRSERVER_AUTH_BASIC_PASSWORD | HTTP basic auth password of the FHIR server to send data to | `""` |
| SERVICES_PSQL_ENABLED | Wether storing resources in a PostgreSQL database should be enabled | false |
| SERVICES_KAFKA_ENABLED | Wether Kafka should be enabled. Note Kafka options below | false |
| SERVICES_KAFKA_PROCESSOR_ENABLED | Enable reading FHIR resources from, and writing them back to a Kafka cluster | false |
| SERVICES_KAFKA_PROCESSOR_GENERATE_OUTPUT_TOPIC_MATCH_EXPRESSION | Allows for dynamically generating the Kafka output topic's name based on the input topic. Used to set a regular expression which is applied to the input topic and the first match is replaced with the value of `SERVICES_KAFKA_GENERATE_OUTPUT_TOPIC_REPLACE_WITH`. You can set this to `"^"` to add a prefix to the output topic. | `""` |
| SERVICES_KAFKA_PROCESSOR_CONSUME_ONLY | Only reads FHIR resources from a Kafka cluster without writing them back | false |
| SERVICES_KAFKA_STORE_FROM_API_ENABLED | Wether storing resources in a Kafka topic should be enabled (only applicable for resources received by the FHIR Gateway's FHIR REST API | false |
| SERVICES_KAFKA_STORE_FROM_API_OUTPUT_TOPIC | Name of the topic where resources received from API should be written to | fhir.gateway.ouput |
For the Kafka configuration and other configuration options,
see [application.yml](src/main/resources/application.yml).
### Running without database persistence
By default, the FHIR gateway persists any received FHIR resource in a PostgreSQL database.
To run without persistence, the following variables both need to be set:
- `SPRING_SERVICE_PSQL_ENABLED="false"`
- `SPRING_SQL_INIT_MODE="never"`
this allows the gateway to start without the database.
## Supported Operations
The FHIR Gateway is not a fully-fledged FHIR server and only supports a subset of the RESTful server
interactions.
### POST/PUT
The Gateway only supports persisting resources that are HTTP POSTed as FHIR Bundles using
the [update-as-create](https://www.hl7.org/fhir/http.html#upsert) semantics.
See [bundle.json](tests/e2e/data/bundle.json) for an example.
### DELETE
FHIR Bundles containing `DELETE` requests are also handled and will result in deleting the resource
specified in the request URL. Note that the resources are marked as `is_deleted` in the Gateway's
PostgreSQL DB instead of being physically deleted.
Note that neither conditional creates nor deletes are supported. While this works:
```json
{
"request": {
"method": "DELETE",
"url": "Patient/234"
}
}
```
This does not:
```json
{
"request": {
"method": "DELETE",
"url": "Patient?identifier=123456"
}
}
```
## Development
Start all fixtures to run the FHIR GW:
```sh
docker compose \
-f dev/docker-compose.dev.yml \
-f dev/docker-compose.gw-deps.yml \
-f dev/docker-compose.exposed.yml up
```
This contains a few optional services: Kafka, a FHIR server, FHIR Pseudonymizer, Vfps. You might simplify the
docker-compose.dev.yml and only include relevant components for development.
Run the FHIR Gateway from your terminal:
```sh
./gradlew :bootRun
```
By default, this runs using Kafka as a source of FHIR resources to process. You can view the generated Kafka topics
at .
## Database Tuning
### Partitioning
If the size of the `resources` table is expected to grow significantly, you can leverage
partitioning to split the stored resources by type. Run the following **before** starting the
FHIR-Gateway to create the `resources` table with partitions for the most common resource types:
```postgresql
CREATE TABLE resources (
id SERIAL,
fhir_id VARCHAR(64) NOT NULL,
type VARCHAR(64) NOT NULL,
data JSONB NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
last_updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
CONSTRAINT fhir_id_unique UNIQUE (fhir_id, type)
) PARTITION BY LIST (type);
CREATE TABLE resources_patient PARTITION OF resources FOR VALUES IN ('Patient');
CREATE TABLE resources_encounter PARTITION OF resources FOR VALUES IN ('Encounter');
CREATE TABLE resources_condition PARTITION OF resources FOR VALUES IN ('Condition');
CREATE TABLE resources_observation PARTITION OF resources FOR VALUES IN ('Observation');
CREATE TABLE resources_medication PARTITION OF resources FOR VALUES IN ('Medication');
CREATE TABLE resources_medication_statement PARTITION OF resources FOR VALUES IN ('MedicationStatement');
CREATE TABLE resources_medication_administration PARTITION OF resources FOR VALUES IN ('MedicationAdministration');
CREATE TABLE resources_procedure PARTITION OF resources FOR VALUES IN ('Procedure');
CREATE TABLE resources_others PARTITION OF resources DEFAULT;
CREATE INDEX resource_id_idx ON resources (id);
CREATE INDEX resource_type_idx ON resources (type);
CREATE INDEX last_updated_at_idx ON resources (last_updated_at DESC);
```
Be sure to set `SPRING_SQL_INIT_MODE=never` before starting the FHIR GW.
This isn't part of the default initialization schema, but may become the default as part of the next
major release.