PATIENT ADMINISTRTAION (PA) Workgroup Development Draft

6.15 Resource Subscription - Content

This resource maintained by the FHIR Management Group Work Group

The subscription resource is used to define a push based subscription from a server to another system. Once a subscription is registered with the server, the server checks every resource that is created or updated, and if the resource matches the given criteria, it sends a message on the defined "channel" so that another system is able to take an appropriate action.

6.15.1 Scope and Usage

This is a candidate resource not yet formally proposed (or approved)

The subscription resource is used to define a push based subscription from a server to another system. Once a subscription is registered with the server, the server checks every resource that is created or updated, and if the resource matches the given criteria, it sends a message on the defined "channel" so that another system is able to take an appropriate action. The server is able to send notifications without any information about the matching resource, or with the entire resource.

Several different types of channels are supported:

  • rest-hook: A post is made to the URL. If the subscription requests that the whole resource is included, the URL is intepreted as the service base
  • websocket: An PING message is sent to the designated URI
  • email/sms: A notification is send to nominated email address or SMS number
  • message: The resource is sent to the application identified in the URI as a message

See below for further discussion of the various channels. Note that sending the entire resource creates security concerns that must be managed by the server.

6.15.2 Boundaries and Relationships

Once a subscription is created, any newly created or updated resources that meet the criteria in the resource cause a notification to be sent using the provided channel. The criteria is a Search string that has the same interpretation as if it were appended to the base URL and submitted using the REST API. Note that the search criteria is applied to the new value of the resource. The consequence of this is that there is no notification when a resource is deleted, or when a resource is updated so that it no longer meets the criteria.

As an alternative to subscriptions, the RESTful API describes a polling-based subscription method using bundles and the history operation. This method of polling allows for a much tighter relationship between the client and the server that doesn't involve missing updates and/or deletes.

Subscriptions are active resources; a server can only accept a subscription if it will execute the specified channel for any resources subsequently received. The subscription is no longer active once it is deleted from the server.

6.15.3 Resource Content

Structure

NameFlagsCard.TypeDescription & Constraintsdoco
.. Subscription DomainResourceA server push subscription criteria
... criteria 1..1stringRule for server push criteria
... contact 0..*ContactPointContact details for source (e.g. troubleshooting)
... reason 1..1stringDescription of why this subscription was created
... status ?!1..1coderequested | active | error | off
SubscriptionStatus (Required)
... error 0..1stringLatest error note
... channel 1..1ElementThe channel on which to report matches to the criteria
.... type 1..1coderest-hook | websocket | email | sms | message
SubscriptionChannelType (Required)
.... endpoint 0..1uriWhere the channel points to
.... payload 1..1stringMimetype to send, or blank for no payload
.... header 0..1stringUsage depends on the channel type
... end 0..1instantWhen to automatically delete the subscription
... tag 0..*CodingA tag to add to matching resources

UML Diagram

XML Template

<Subscription xmlns="http://hl7.org/fhir"> doco
 <!-- from Resource: id, meta, implicitRules, and language -->
 <!-- from DomainResource: text, contained, extension, and modifierExtension -->
 <criteria value="[string]"/><!-- 1..1 Rule for server push criteria -->
 <contact><!-- 0..* ContactPoint Contact details for source (e.g. troubleshooting) --></contact>
 <reason value="[string]"/><!-- 1..1 Description of why this subscription was created -->
 <status value="[code]"/><!-- 1..1 requested | active | error | off -->
 <error value="[string]"/><!-- 0..1 Latest error note -->
 <channel>  <!-- 1..1 The channel on which to report matches to the criteria -->
  <type value="[code]"/><!-- 1..1 rest-hook | websocket | email | sms | message -->
  <endpoint value="[uri]"/><!-- 0..1 Where the channel points to -->
  <payload value="[string]"/><!-- 1..1 Mimetype to send, or blank for no payload -->
  <header value="[string]"/><!-- 0..1 Usage depends on the channel type -->
 </channel>
 <end value="[instant]"/><!-- 0..1 When to automatically delete the subscription -->
 <tag><!-- 0..* Coding A tag to add to matching resources --></tag>
</Subscription>

Structure

NameFlagsCard.TypeDescription & Constraintsdoco
.. Subscription DomainResourceA server push subscription criteria
... criteria 1..1stringRule for server push criteria
... contact 0..*ContactPointContact details for source (e.g. troubleshooting)
... reason 1..1stringDescription of why this subscription was created
... status ?!1..1coderequested | active | error | off
SubscriptionStatus (Required)
... error 0..1stringLatest error note
... channel 1..1ElementThe channel on which to report matches to the criteria
.... type 1..1coderest-hook | websocket | email | sms | message
SubscriptionChannelType (Required)
.... endpoint 0..1uriWhere the channel points to
.... payload 1..1stringMimetype to send, or blank for no payload
.... header 0..1stringUsage depends on the channel type
... end 0..1instantWhen to automatically delete the subscription
... tag 0..*CodingA tag to add to matching resources

UML Diagram

XML Template

<Subscription xmlns="http://hl7.org/fhir"> doco
 <!-- from Resource: id, meta, implicitRules, and language -->
 <!-- from DomainResource: text, contained, extension, and modifierExtension -->
 <criteria value="[string]"/><!-- 1..1 Rule for server push criteria -->
 <contact><!-- 0..* ContactPoint Contact details for source (e.g. troubleshooting) --></contact>
 <reason value="[string]"/><!-- 1..1 Description of why this subscription was created -->
 <status value="[code]"/><!-- 1..1 requested | active | error | off -->
 <error value="[string]"/><!-- 0..1 Latest error note -->
 <channel>  <!-- 1..1 The channel on which to report matches to the criteria -->
  <type value="[code]"/><!-- 1..1 rest-hook | websocket | email | sms | message -->
  <endpoint value="[uri]"/><!-- 0..1 Where the channel points to -->
  <payload value="[string]"/><!-- 1..1 Mimetype to send, or blank for no payload -->
  <header value="[string]"/><!-- 0..1 Usage depends on the channel type -->
 </channel>
 <end value="[instant]"/><!-- 0..1 When to automatically delete the subscription -->
 <tag><!-- 0..* Coding A tag to add to matching resources --></tag>
</Subscription>

 

Alternate definitions: Schema/Schematron, Resource Profile (XML, JSON)

6.15.3.1 Terminology Bindings

PathDefinitionTypeReference
Subscription.status The status of a subscriptionRequiredhttp://hl7.org/fhir/subscription-status
Subscription.channel.type The type of method used to execute a subscriptionRequiredhttp://hl7.org/fhir/subscription-channel-type

6.15.4 Safety and Security

Executing each of the channels documented below involves the server sending a communication that will reveal information about the client and server relatinoship, and, if the entire resource is sent, administrative or clinical information that may be quite sensitive and/or protected under law. Servers are responsible for ensuring appropriate security is employed for each channel. The subscription resource does not address these concerns directly - it is assumed that these are administered by other configuration. For instance, a server might maintain a whitelist of acceptable servers for the rest-create/rest-update methods.

Emails should generally be secured using some technique such as Direct.

6.15.5 Managing Subscriptions and Errors

A subscription is defined by creating the subscription on the server. When the subscription is created by the client, it sets the status to "requested". After POSTing the subscription, the client parses the Location header and saves the new Subscription's logical id for use in subsequent operations.

The criteria is subject to the same limitations as the client that created it, such as access to patient compartments etc. Note that the subscription remains active after the client access tokens expire.

Once the server has activated the subscription, it sets the status to "active" (note: the server can do this as it accepts the resource if it wants).

An appropriately authorized client can use search and/or history operations to see what subscriptions are currently active on the server. Once the subscription is no longer desired, the client deletes the subscription from the server.

The server may retry the notification a fixed number of times and/or refer errors to its own alert logs. If the notification fails, the server should set the status to 'error', and mark the error in the resource. If the notification succeeds, the server should update the status to "active again. If a subscription fails consistently a server may choose set the subscription status to off, and stop trying to send notifications.

If a subscription nominates a fixed end date, the server automatically deletes it at the specified time.

6.15.6 Channels

6.15.6.1 REST Hook

This uses an empty POST message to alert the client that new results are available.

POST /Subscription

{
  "resourceType": "Subscription",
  "criteria": "/Observation?name=http://loinc.org|1975-2&_format=json",
  "channel": {
    "type": "rest-hook",
    "url": "https://biliwatch.com/customers/mount-auburn-miu/on-result",
    "header": ["Authorization: Bearer secret-token-abc-123"]
  }
}

When a resource is created or updated that meets the criteria, the server sends a POST request with no body to the nominated URL.

When the client receives a POST to https://biliwatch.com/customers/mount-auburn-miu/on-result, it re-issues the criteria as a query to the server, appending &_since=:last (where :last is replaced by the time at which the client last checked). In this way it can fetch all new relevent Observations.

Since payload is missing, the data in the resources is only available through the REST API, which helps consolidate authorization and authentication logic. The server must append the headers, if any are given, to the POST request that it makes to the client.

Alternatively, the server can be asked to send the entire resource to a nominated FHIR end point. This is usually appropriate for defining routing rules within a managed eco-system such as a healthcare institution.

  "channel": {
    "type": "rest-hook",
    "url": "https://internal.acme.com/research/saturn",
    "payload": "application/xml+json"
  }

This requests that a server forward a copy of any matching resource in json format to the nominated server as an Update operation using the nominated URL as the service base. In order to execute this channel, the server must know how to authenticate appropriately with the destination server. This can be done by the subscription resource providing an authentication header for the server to use, or alternatively, the server may be specifically configured to be able to use the nominated server.

6.15.6.2 WebSockets

Subscriptions are created exclusively via the FHIR REST API. But notifications need not occur via REST. Indeed, some clients may be unable to expose an outward-facing HTTP server to receive triggered notifications. For example, a pure client-side Web app or mobile app may want to subscribe to a data feed without polling using the /history operation. This can be accomplished using a websocket notification channel.

A client can declare its intention to listen via Web Sockets:

  "channel": {
    "type": "webSocket"
  }

The client would then initiate a Web Socket connection to the server, at a URL advertised in the FHIR server's conformance statement (subscriptions/webSocketUrl (todo)). A simple protocol is used to listen for notifications:

  • Client connects a secure Web Socket to the hospital's webSocketUrl.
  • Client authenticates to server using a server-specified Web socket protocol (e.g. OAuth bearer token presentation).
  • Client sends a bind :id message over the socket (using the logical id of the subscription). For example, the client might issue: bind 123).
  • Server responds with a "bound :id" message to acknowledge.
  • Server sends a "ping :id" message to notify the client each time a new result is available

6.15.6.3 Email/SMS

A client can register for its user to receive notifications by email:
  "channel": {
    "type": "email",
    "url": "mailto:mt-auburn-results@direct.biliwatch.com",
    "header": "A new bilirubin result has arrived!"
  }

The server would send a new message for each matching resource. The body of the email may be empty, or it may contain a refernce to the search or the matching resource. It is at the discretion of the server as to how much information to provide. The email should be secured appropriately, such as using Direct, as specified by the rules of the applicable jurisdictions.

SMS works very similarly:

  "channel": {
    "type": "sms",
    "url": "tel:+1555-345-5555"
  }

Note: SMS messages are extremely limited in size, so payload should be set to false, and most servers will refuse to send payloads in SMS.

6.15.6.4 Messaging

Todo

6.15.7 Search Parameters

Search parameters for this resource. The common parameters also apply. See Searching for more information about searching in REST, messaging, and services.

NameTypeDescriptionPaths
contacttokenContact details for source (e.g. troubleshooting)Subscription.contact
criteriastringRule for server push criteriaSubscription.criteria
payloadstringMimetype to send, or blank for no payloadSubscription.channel.payload
statustokenrequested | active | error | offSubscription.status
tagtokenA tag to add to matching resourcesSubscription.tag
typetokenrest-hook | websocket | email | sms | messageSubscription.channel.type
urluriWhere the channel points toSubscription.channel.endpoint