Netherlands - Generic Functions for data exchange Implementation Guide
0.3.0 - ci-build Netherlands flag

Netherlands - Generic Functions for data exchange Implementation Guide, published by Stichting Nuts. This guide is not an authorized publication; it is the continuous build for version 0.3.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/nuts-foundation/nl-generic-functions-ig/ and changes regularly. See the Directory of published versions

Notification

Page standards status: Draft

Introduction

This page specifies how FHIR-based event notifications are exchanged between organizations in the Dutch healthcare ecosystem. It describes a generic transport layer that other Implementation Guides and use cases (e.g. Notified Pull) build upon: a sending organization signals to a receiving organization that something it cares about has happened, and the receiver pulls the current state from the sender's FHIR endpoint.

The framework is based on the FHIR Subscription Framework, implemented in FHIR R4 via the Subscriptions R5 Backport for R4. It uses three core resources: SubscriptionTopic (defining events and triggers), Subscription (describing the receiver's interest in notifications), and notification Bundles (carrying event-notification, handshake-notification or heartbeat-notification). Clients request notifications based on specific topics, and servers send them over a configured channel.

Key design principles include:

  • International standards: the solution is based on the HL7 FHIR Subscription Framework, lowering the bar for international (European) data exchange and adoption by internationally operating software vendors.
  • Out-of-band (server-managed) style: for some SubscriptionTopics, the subscription is created by the sender (the Subscription Server), using the endpoint of the receiver that was communicated 'out-of-band' (using GF Addressing). A client-initiated subscription MAY be supported.
  • Thin notifications, authoritative source: notifications carry no clinical content. The sender remains the source of truth; the receiver pulls the referenced resource from the sender's FHIR endpoint to obtain the current state.

Solution overview

Here is a brief overview of the processes that are involved:

  1. At the sending organization (the Subscription Server) a Subscription is registered for the receiving organization (the Subscription Client) against an agreed SubscriptionTopic. How this Subscription is created is use-case defined (in-band or out-of-band); see Subscription.
  2. After registration, the Subscription Server sends a handshake-notification to confirm the channel and updates Subscription.status accordingly.
  3. Whenever an event matches the topic and filter, the Subscription Server sends an event-notification Bundle to the receiver, with a monotonically increasing event-number.
  4. At predefined intervals the Subscription Server sends a heartbeat-notification so the receiver can detect channel outages.
  5. The Subscription Client consumes notifications, detects missed events using event-number, and uses the $event and $status operations on the sender to catch up or query state.
  6. The Subscription Client may fetch the resource that were mentioned in the notification bundle.

Components (actors)

Subscription Server

The Subscription Server runs at the sending party and is responsible for managing subscriptions and delivering notifications. It MUST:

  • create Subscription resources for the agreed (Out-of-band Managed) SubscriptionTopic(s).
  • send handshake-notification Bundles when Subscription.status is requested (with retries) and update Subscription.status accordingly;
  • send heartbeat-notification Bundles at predefined intervals (with retries) and update Subscription.status accordingly;
  • send event-notification Bundles, incrementing event-number in a concurrent-safe way;
  • support the Subscription resource so clients can query state and catch up on missed events:
    • support the $status and $event operations;
    • support the read and search interaction with search parameters status, criteria, channel.endpoint, channel.type and channel.payload;

The Subscription Server MAY support creation of subscriptions by Subscription Clients (In-band Managed Subscriptions).

Subscription Client

The Subscription Client runs at the receiving party and consumes notifications. It MUST:

  • receive notification Bundles at its notification endpoint (and forward/act on them);
  • check each notification Bundle to ensure no events were missed, using the highest event-number it has successfully processed. Missed notifications are caught up using the sender's $event operation;
  • check at predefined intervals whether a heartbeat-notification was missed. If so, the subscription status is queried using the sender's $status operation.

The Subscription Client, being responsible for resolving failures, should also track the subscription's state to highlight and fix any erroneous communication.

Data models

A brief description of the data models used in this guide:

Subscription

A Subscription is created at the sending organization for a receiving organization before any notifications flow. The pattern is a broad, long-lived Subscription per partner for a given use-case topic, not a Subscription per case. A single Subscription covers all events that match the topic and filter between the two partners.

How the Subscription is created is use-case defined: it MAY be created in-band (the client POSTs a Subscription to the server) or out-of-band.
For out-of-band managed subscriptions, the receiver's notification endpoint is typically resolved via the addressing function (Care Services Query Directory); see the endpoint discovery example. An Endpoint capable of receiving notifications is defined by connectionType = hl7-fhir-rest and .payloadType = Subscription (see Endpoint profile.

The server MUST check for an existing Subscription for the client before sending notifications; beyond that, the creation mechanism does not affect runtime behavior.

A Subscription SHALL:

  • set Subscription.status = active while in use and off to retire the channel;
  • carry a SubscriptionTopic canonical URL on Subscription.criteria (using the Backport IG backport-topic-canonical extension where the criteria element cannot itself hold the canonical) and MAY carry a refining filter using backport-filter-criteria;
  • set Subscription.channel.type = rest-hook with the receiver's notification endpoint;
  • set Subscription.channel.payload = application/fhir+json and the Backport IG backport-payload-content extension to id-only.

A Subscription example is in the IG artifacts: a long-lived Subscription at one organization that fires whenever a Task is owned by a partner organization identified by URA.

Notification Bundle

Each event matching the SubscriptionTopic and filter triggers one notification to the receiver. The notification is a FHIR Bundle of type history conforming to the Backport IG backport-subscription-notification profile. It contains a Parameters resource (SubscriptionStatus) conforming to backport-subscription-status-r4 with at minimum:

  • subscription — reference to the registered Subscription;
  • statusactive or off;
  • typeevent-notification, handshake-notification or heartbeat-notification;
  • notification-event.event-number — monotonically increasing, used by the receiver to detect missed events;
  • notification-event.timestamp — when the event occurred at the sender;
  • notification-event.focus — reference to the resource the event is about (e.g. the Task on the sender).

The notification carries no clinical content. With id-only payload the receiver learns only that a referenced resource has changed and pulls it from the sender's FHIR endpoint to obtain the current state.

A notification Bundle example and its SubscriptionStatus Parameters are in the IG artifacts; together they notify a partner that it is the proposed owner of a Task held at the sender.

SubscriptionTopic

A SubscriptionTopic defines the events that trigger notifications and the resource shape they apply to. SubscriptionTopics are owned and published per use case; each Implementation Guide that builds on this transport layer is responsible for defining (or referencing) the topics it uses, and for binding them to a canonical URL referenced by Subscription.criteria.

Security

Notification endpoints MUST require mTLS. Authentication and authorization for notifications and for the subsequent pull on the sender's FHIR endpoint follows the GF Authorization specification.

Because notifications use id-only payload, the notification Bundle itself contains no clinical content and minimal personal data. The actual resource content is only disclosed when the receiver pulls it from the sender's FHIR endpoint, where the sender re-evaluates authorization at the moment of access.

Example use cases

Use case: notifying a partner of a new Task

A sending organization holds a Task that names a partner organization (identified by URA) as its (proposed) owner. A long-lived Subscription exists at the sender for that partner against a topic that fires when a Task's owner matches the partner's URA. When the Task is created, the Subscription Server sends an event-notification Bundle to the partner's notification endpoint; the partner reads the Task from the sender to learn what to do next.

The example artifacts for this scenario are the Subscription and the notification Bundle with its SubscriptionStatus Parameters.

Roadmap for Notifications

Potential future enhancements include:

  • a registry of nationally agreed SubscriptionTopic canonical URLs;