Mock Server, based on HAPI FHIR JpaServer, that implements the ISiK Specification.
2.7K
This is a simple implementation of ISiK Level 5 specifications to be used as a simulation for testing purposes. It is based on the HAPI FHIR Starter Project.
See ReleaseNotes.md for all information regarding the (newest) releases.
To build and run the mock server, you can use Docker or deploy the WAR file on a Apache Tomcat server.
You can run the server as a Docker Container with an in-memory Database by issuing the command:
docker run --rm -it -p 8080:8080 gematik1/isik-mock-server:latest
You can run the server as a Docker Container with dedicated PostgreSQL Database by issuing the command:
docker compose --project-name isik-mock-server up -d
The server will then be accessible at http://localhost:8080/fhir and eg. http://localhost:8080/fhir/metadata after some seconds (usually 30-60).
Once started the server is accessible at http://localhost:8080/fhir and the CapabilityStatement will be found at http://localhost:8080/fhir/metadata.
Please refer to the main HAPI FHIR Jpa Server documentation for further information about the general server functionality: HAPI FHIR Jpa Server Documentation
This Mock Server comes with some example FHIR Resources that are loaded on startup. You can add your own resources by providing a folder containing FHIR Resources in JSON or XML format.
To do this, you need to set the property example-fhir-resources.directory in the application.yml file to the path of
your folder. The server will then load all the FHIR Resources from that folder recursively on startup.
If you use the Docker Image, you can mount a volume in the container to provide the folder with your custom resources. For example:
docker run --rm -it -p 8080:8080 \
-v /path/to/your/resources:/fhir-resources \
-e EXAMPLE_FHIR_RESOURCES_DIRECTORY=/fhir-resources \
gematik1/isik-mock-server:latest
Although ISiK generally permits compatibility with non‑ISiK‑compliant instances for historical data (particularly when returning data in a READ interaction), this server implementation does not adopt a liberal approach that would accept such instances during a CREATE interaction. The server rejects CREATE requests if the supplied resources are not conformant with an existing ISiK profile.
This ISiK server may persist instances that are not ISiK compliant. These emulate legacy or historical data which a client should still be able to process in a READ interaction using appropriate error handling.
gematik ReferenzvalidatorEvery FHIR resource that is being sent to the server via a POST or PUT request is being validated with
the gematik Referenzvalidator using
the ISIK-5 one. If a resource
is not valid it gets rejected and a response with an OperationOutcome containing the validation errors is being sent
back to the client. Only resources that are valid will be accepted.
Additional Details:
/$.. (e.g. $book) are not validated with the Referenzvalidator. Validation for such
operations happens internally.ISiKMedikationTransaction for transaction bundles).The server accepts XML and JSON. Clients can choose between XML and JSON representation, but must indicate which
representation has been selected in the HTTP Accept and Content-Type
headers, cf. ISiK v5 Specification).
The validation of Media-Types is skipped only for Binary resources.
The server now validates the fhirVersion parameter in Accept/Content-Type headers and rejects anything other than
4.0 (returns 406).
Appointment/$bookThe server implements the Operation for booking Appointments according to the official ISiK v5 Specification.
The $book operation accepts both a bare Appointment and a Parameters resource with named parameters (
appt-resource, schedule, cancelled-appt-id, patient, related-person).
Plausibility checks:
proposedhttp://terminology.hl7.org/CodeSystem/service-typefreeOther implemented features:
422, or 409 in
case of conflicts.patient or related-person are supplied in Parameters, the server resolves existing or creates new resources.Appointment.start / .end are not set but a Slot is referenced, values are populated from the SlotAppointment is one between proposed/cancelled/waitlist, the presence of start/end fields
for these statuses is not validatedisik.appointment.book.pending-enabled has been introduced: when enabled, $book returns status
pending (HTTP 202) instead of booked (HTTP 201)Clients can also book Appointments asynchronously. To do this they need to add a Prefer-Header that contains
respond-async. The server will then send a response with status 202 and a Content-Location-Header that contains
the url where the client can later access the result of the asynchronous booking job. To access the result of the
asynchronous job the client needs to do a GET request with the url from the Content-Location-Header.
The server implements updating Appointments according to the chapter Aktualisierung / Absage eines Termins from the
official ISiK v5 Specification.
It supports Patch (PATCH) on Appointments using a Parameters resource, not a direct PUT of the full resource.
Plausibility checks:
Appointment.slot MUST NOT be changedAppointment.start MUST NOT be changedAppointment.end MUST NOT be changedAppointment.participant.actor.where(resolve() is Patient) MUST NOT be changedactive=falseslot, start, end, participant.actor) only accept replace operations and reject add/
removeThe server implements rescheduling of Appointments as described in the cancelled-appt-id parameter in the
official ISiK v5 Specification.
Booking Appointments need to be fulfilled here as well.cancelled.cancelled (either via $book rescheduling or via PATCH), all referenced Slots
are automatically freed (set back to free).The server can enrich incoming DocumentReferences that are going to be created, including those inside transaction
Bundles. Embedded base64 encoded attachment data is extracted into a separate Binary resource and the attachment URL
is replaced with the Binary's URL.
The enrichment can fail if the referenced Patient or Encounter do not exist on the server.
When a new DocumentReference includes a relatesTo entry with code replaces, the server automatically sets the status
of the referenced (previous) document to superseded.
The server completes any missing XDS class and type codes using the transmitted KDL code and returns them in
DocumentReference.type or DocumentReference.category. The XDS codes determined from the KDL code using the
ConceptMaps published as part of the KDL specification. The XDS codes are required for
cross-institutional document exchange via IHE XDS or MHD or for the transmission of documents to the patient's
ePA.
DocumentReference/$generate-metadataThe server supports the Operation of generating of metadata as described in the official ISiK v5 Specification.
DocumentReference/$update-metadataThe server supports the Operation of generating of metadata as described in the official ISiK v5 Specification.
The example-fhir-resources.validation.enabled flag controls whether example FHIR resources are validated during server
startup. Validation ensures resource integrity but significantly slows down the server's startup. By default, it is
disabled (set in application.yml) to speedup development. If you want to validate the example resources on startup,
enable the flag by adding the following VM option to your runtime configuration:
-Dexample-fhir-resources.validation.enabled=true
when the validation is enabled, the startup time might vary significantly based on the number of example resources and the performance of the machine, but it can take up to several minutes.
The server handles incoming Bundle Resources with Bundle.type = DOCUMENT, validating the following requirements:
Composition has a narrative (text)Patient (subject) exists on the server (searched by identifier)Encounter exists on the server (searched by identifier)The server supports Requests with transaction Bundles, accepting Bundle Resources with Bundle.type = TRANSACTION:
it validates incoming transaction bundles against the ISiKMedikationTransaction profile and for outgoing
transaction-response bundles, the server enriches them with Bundle.meta.profile set to
ISiKMedikationTransactionResponse and derives Bundle.entry.fullUrl from entry.response.location.
$merge and Subscription NotificationsThe server implements the HL7 Patient $merge operation and FHIR
Subscription Topic notifications based on
the Subscriptions R5 Backport IG. Only REST-hook subscriptions
are supported.
The operation is invoked at type level on Patient/$merge. Source and target patient may be supplied either as a
direct reference (source-patient / target-patient, type Reference) or via identifiers
(source-patient-identifier / target-patient-identifier, type Identifier) — exactly one of the two must be given
per patient. Optional parameters: result-patient (the expected final state of the target patient) and preview
(boolean; when true the merge is validated but not persisted and no notification is sent).
The operation returns a Parameters resource with an outcome (OperationOutcome) and the merged result-patient.
The merge sets Patient.link of type replaced-by on the (deactivated) source patient pointing to the target, and a
replaces link on the target patient. The replaces link is set as a logical reference (via the source patient's
MR identifier) rather than a literal reference, because the ISiK specification permits the obsolete source patient to be
deleted — a literal reference would then dangle. For this reason both patients must carry a populated PID
(Identifier.type = MR).
The topic-based event notification itself (matching active subscriptions to a topic, building the notification bundle
and
delivering it to the rest-hook endpoint) is handled by HAPI's built-in machinery — SubscriptionTopicConfig and
SubscriptionProcessorConfig, enabled in HapiSubscriptionBeans. The merge operation only triggers it via HAPI's
SubscriptionTopicDispatcher (see PatientMergeOperationProvider#patientMerge).
The classes in this repository cover the surrounding subscription lifecycle:
| Concern | Class(es) |
|---|---|
| Trigger the topic notification on merge | PatientMergeOperationProvider (calls HAPI's SubscriptionTopicDispatcher) |
Handshake on status=requested | SubscriptionCreateHandshakeInterceptor → SubscriptionHandshakeSender → SubscriptionHandshakeFinalizer |
| Heartbeat | SubscriptionHeartbeatService, HeartBeatDispatchService, HeartbeatAwarePayloadBuilder |
When a new Subscription is created with status=requested, the server immediately sends a handshake notification
to the subscriber's endpoint:
status=active).status=error.This ensures that only reachable subscribers become active.
For active subscriptions the server supports heartbeat notifications as specified in the backport IG:
backport-heartbeat-period extension on the subscription channel.heartbeat to the subscriber's endpoint when the interval is
due.The following steps simulate the merge-notification workflow. A Postman Collection with ready-made requests is available
in the src/test/resources/subscription folder of this repository.
You need a REST endpoint that accepts POST /Bundle. Options:
POST, and use the displayed URL as
the subscription endpoint.docker run -p 8080:8080 \
-e hapi.fhir.allowed_bundle_types=COLLECTION,DOCUMENT,MESSAGE,TRANSACTION,TRANSACTIONRESPONSE,BATCH,BATCHRESPONSE,HISTORY,SEARCHSET \
gematik1/isik-mock-server:latest
Steps:
Postman: 1. Send Patients).https://gematik.de/fhir/isik/SubscriptionTopic/patient-merge, setting .endpoint to your
receiver URL (Postman: 2. Subscribe to Patient merge topic).Patient/$merge, either by direct reference with source-patient / target-patient
(Postman: 3a. merge patients (by reference)) or by identifier with source-patient-identifier /
target-patient-identifier (Postman: 3b. merge patients (by identifier)).Note: When using Postman mock servers, a stack trace may appear in the server log because Postman responds with
Content-Type: text/htmlinstead ofapplication/fhir+json. This does not affect notification delivery.
As specified in the ISiK Connect Implementation Guide, the server implements the SMART-on-FHIR v2 Capabilities.
The functionality can be enabled by configuring the following properties:
spring:
security:
oauth2:
enable: true
resourceserver:
jwt:
# SpringBoot specific properties for the Issuer Server
issuer-uri: http://authorization.server.example/realms/fhir
jwk-set-uri: http://authorization.server.example/realms/fhir/protocol/openid-connect/certs
# SMART on FHIR Endpoints
smart:
# Defines the current FHIR Resource Server
fhir-base-url: http://localhost:8080/fhir
# Defines the Authorization Server
authorization-server-url: http://authorization.server.example/realms/fhir
When the property spring.security.oauth2.enable is set to true, the server will require an authorization for
accessing resources, following the SMART-on-FHIR specification.
The following Endpoints will be registered in the server:
| Endpoint | Description |
|---|---|
/fhir/.well-known/smart-configuration | Provides the SMART-on-FHIR configuration |
/fhir/token/introspect | Provides the Introspection of Token. Internally, it routes the request to the Authorization Server |
/fhir/launch | Provides the SMART-App-Launch endpoint |
NOTE: When the property spring.security.oauth2.enable is set to false, the whole SpringBoot Security context is
disabled, including the session management and the handling of CSRF tokens, which may interfere with existing
integration tests in this repository.
To tests the SMART Capabilities, an initial Keycloak setup has been provided, with the required scope mappings, extending the Docker Compose environment:
docker compose --project-name isik-mock-server -f docker-compose.yml -f docker-compose.smart.yml up -d
If you want to contribute, please check our CONTRIBUTING.md.
Copyright 2025-2026 gematik GmbH
Apache License, Version 2.0
See the LICENSE for the specific language governing permissions and limitations under the License
We take open source license compliance very seriously. We are always striving to achieve compliance at all times and to improve our processes. This software is currently being tested to ensure its technical quality and legal compliance. Your feedback is highly valued. If you find any issues or have any suggestions or comments, or if you see any other ways in which we can improve, please open a GitHub issue or a ticket within Anfrageportal ISiK.
Content type
Image
Digest
sha256:8f3d98fbb…
Size
673.6 MB
Last updated
about 1 month ago
docker pull gematik1/isik-mock-server