Topic Subscriptions
FHIR R4 Subscriptions are based on a single Subscription resource that defines both the criteria for triggering a resource change notification as well as the channel for sending a notification.
FHIR R5 Subscriptions separates these functions. The criteria for triggering a notification is now defined in a new SubscriptionTopic resource while the channel delivery detail remains in the Subscription resource. The two are linked via a canonical identifier:
Subscription.topic SubscriptionTopic.url
In R5, multiple Subscription resources can subscribe to the same SubscriptionTopic, and refine the notifications they accept via filters.
Also, R5 SubscriptionTopic triggers are greatly expanded from the criteria available in R4. A R4 Subscription contains a single query string, e.g. Observation?code=DIAB
that will only match CREATE
and UPDATE
operations and can only evaluate the most recent version of the resource. A R5 SubscriptionTopic, on the other hand, defines a rich collection of triggers that can match details of the previous version of a resource as well as the new version. R5 SubscriptionTopic triggers can detect specific resource state transitions, or DELETE
operations on specified resources. R5 SubscriptionTopic resources can also define arbitrary business event triggers that have nothing to do with resource changes.
FHIR R5 functionality is available to FHRI R4 systems in one of two ways:
FHIR R4B extends FHIR R4 by adding the SubscriptionTopic and SubscriptionStatus resources as well as defining a number of extensions to support R5-style subscriptions.
The FHIR R5 Subscription Backport to R4 offers limited capability to R4 systems via extensions and namespaces defined in an IG.
Limited Subscription R5 functionality, as well as the backports to R4B and R4 is now available in Smile CDR. Here is a summary of what is currently supported.
Feature | R5 | R4B | R4 | Notes |
---|---|---|---|---|
Topic Subscription | ✔ | ✔ | ✔ | |
SubscriptionTopic | ✔ | ✔ | ||
SubscriptionStatus | ✔ | ✔ | ||
Notification Bundle | ✔ | ✔ | ✔ | |
Event Notification | ✔ | ✔ | ✔ | See "Dispatching Subscription Notifications" below |
Cross-partition matching | Cross-partition matching is currently only supported for DSTU3 and R4 (i.e. non-topic-based) Subscriptions | |||
Subscription/$status |
This list does not cover all fields, just the most common fields used in matching and delivery logic.
Resource | Field | R5 | R4B | R4 | Notes |
---|---|---|---|---|---|
SubscriptionStatus | eventsSinceSubscriptionStart | ~ | ~ | Currently this only counts the number of deliveries for this subscription on this server | |
SubscriptionStatus | notificationEvent.eventNumber | ~ | ~ | This is the same as eventsSinceSubscriptionStart and is only unique on the server it is running on | |
SusbcriptionTopic | queryCriteria.previous | ✔ | ✔ | ||
SusbcriptionTopic | queryCriteria.current | ✔ | ✔ | ||
SusbcriptionTopic | queryCriteria.requireBoth | ✔ | ✔ | ||
SusbcriptionTopic | queryCriteria.resultForCreate | ||||
SusbcriptionTopic | queryCriteria.resultForDelete | ||||
SusbcriptionTopic | fhirPathCriteria | ||||
SusbcriptionTopic | canFilterBy | The system assumes all search parameters are valid filters | |||
SusbcriptionTopic | notificationShape | E.g. include, revinclude | |||
Susbcription | filterBy.resourceType | ✔ | ✔ | ✔ | |
Susbcription | filterBy.filterParameter | ✔ | ✔ | ✔ | |
Susbcription | filterBy.comparator | ~ | ~ | ~ | only EQ and NE are currently supported. The R4 backport currently only supports EQ. |
Susbcription | filterBy.modifier | ||||
Susbcription | filterBy.value | ✔ | ✔ | ✔ | |
Susbcription | content | ~ | ~ | ~ | Only full-resource is supported |
In most cases the resource trigger for event notification will be fully defined within a SubscriptionTopic and the matching and delivery will happen automatically. However for event triggers, or in the case of R4 where there are no SubscriptionTopic resources, delivery of notifications to topic subscriptions must be triggered manually. This is done in Java through the use of the SubscriptionTopicDispatcher
service. This service can be autowired into an interceptor or other Java extension. There are two methods available. Both methods return the number of notifications successfully queued for delivery.
int mySubscriptionTopicDispatcher.dispatch(String theTopicUrl, List<IBaseResource> theResources, RestOperationTypeEnum theRequestType)
Parameter | Description |
---|---|
theTopicUrl | Deliver to subscriptions for this topic |
theResources | The list of resources to deliver. The first resource will be the primary "focus" resource per the Subscription documentation. This list should not include the SubscriptionStatus. The SubscriptionStatus will be added as the first element to the delivered bundle. The reason for this is that the SubscriptionStatus needs to reference the subscription ID, which is not known until the bundle is delivered. |
theRequestType | The type of request that led to this dispatch. This determines the request type of the bundle entries |
If filtering is required, then the following method can be used:
int mySubscriptionTopicDispatcher.dispatch(SubscriptionTopicDispatchRequest theSubscriptionTopicDispatchRequest)
The SubscriptionTopicDispatchRequest
constructor has the following fields:
Parameter | Description |
---|---|
theTopicUrl | Deliver to subscriptions for this topic |
theResources | The list of resources to deliver. The first resource will be the primary "focus" resource per the Subscription documentation. This list should not include the SubscriptionStatus. The SubscriptionStatus will be added as the first element to the delivered bundle. The reason for this is that the SubscriptionStatus needs to reference the subscription ID, which is not known until the bundle is delivered. |
theSubscriptionTopicFilterMatcher | is used to match the primary "focus" resource against the subscription filters |
theRequestType | The type of request that led to this dispatch. This determines the request type of the bundle entries |
theInMemoryMatchResult | Information about the match event that led to this dispatch that is sent to SUBSCRIPTION_RESOURCE_MATCHED |
theRequestPartitionId | The request partitions of the request, if any. This is used by subscriptions that need to perform repository operations as a result of the notification |
theTransactionId | The transaction ID of the request, if any. This is used by subscriptions that need to perform repository operations as a result of the notification |
Here is the definition of the ISubscriptionTopicFilterMatcher
interface:
public interface ISubscriptionTopicFilterMatcher {
InMemoryMatchResult match(CanonicalTopicSubscriptionFilter theCanonicalTopicSubscriptionFilter, IBaseResource theIBaseResource);
}