Release 4 Snapshot 3: Connectathon 32 Base

This page is part of the Snapshot #3 for FHIR Specification (v4.0.1: R4 - Mixed Normative and STU ) in it's permanent home (it will always be available at this URL). The current version which supercedes this version is 5.0.0 R5 , released to support Connectathon 32 . For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4 R3 R2

3.4 Messaging using FHIR Resources

Example StructureDefinition/patient-relatedPerson (XML)

FHIR Infrastructure notification The content is not necessarily intended to be current, and it can be reprocessed, though there may be version issues created by processing old notifications.
Patient Administration Work Group Maturity Level : 3 N/A Standards Status : Trial Use FHIR Resources can be used in a traditional messaging context, much like HL7 v2 (see detailed comparison ). Applications asserting conformance to this framework claim to be conformant to "FHIR messaging" (see Conformance ). In FHIR messaging, a "request message" is sent from a source application to a destination application when an event happens. Events mostly correspond to things that happen in the real world. The request message consists of a Bundle identified by the type "message", with the first resource in the bundle being a MessageHeader resource. The MessageHeader resource has a code - the message event - that identifies the nature of the request message, and it also carries additional request metadata. The other resources in the bundle depend on the type of the request. The events supported in FHIR, along with the resources that are included in them, are defined below. The destination application processes the request and returns one or more response messages which are also a bundle of resources identified by the type "message", with the first resource in each bundle being a MessageHeader resource with a response section that reports the outcome of processing the message and any additional response resources required. Example Request Message Example Response Message 3.4.1 Basic Messaging Assumptions This specification assumes that content will be delivered from one application to another by some delivery mechanism, and then one or more responses will be returned to the source application. The exact mechanism of transfer is irrelevant to this specification, but may include file transfer, HTTP based transfer, MLLP (HL7 minimal lower layer protocol), MQ series messaging or anything else. The only requirement for the transfer layer is that requests are sent to a known location and responses are returned to the source of the request. This specification considers the source and destination applications as logical entities, and the mapping from logical source and destination to implementation specific addresses is outside the scope of this specification, though this specification does provide a direct delivery mechanism below. The agreements around the content of the messages and the behavior of the two applications form the "contract" that describes the exchange. The contract will add regional and local agreements to the rules defined in this specification. This specification ignores the existence of interface engines and message transfer agents that exist between the source and destination . Either they are transparent to the message/transaction content and irrelevant to this specification, or they are actively involved in manipulating the message content (in particular, the source and destination headers are often changed). If these middleware agents are modifying the message content, then they become responsible for honoring the contract that applies (including applicable profiles) in both directions. A key aspect of a message is the impact of its content: 3.4.1.1 The impact of the content of a message. consequence The message represents/requests a change that should not be processed more than once; e.g., making a booking for an appointment. Informative currency The message represents a response to query for current information. Retrospective processing is wrong and/or wasteful.
Some Events defined by FHIR are assigned to one of these categories, but others are not able to be categorized in advance, and the category must be determined by the content, context, or use case. 3.4.1.1.1 Example: Elevation from Notification to Consequence When it is necessary to receive an acknowledgement from multiple parties for a message of notification it becomes a message of consequence: The sender will have to send multiple messages, even if they have the same endpoint. Local protocol requires notification of all lab values Local protocol requires that critical values must be acknowledged by both the ordering and primary provider. Therefore a message of notification becomes a message of consequence. Two messages SHALL be sent, each with a unique identifier. One to the ordering provider One to the primary provider

Applications that implement reliable messaging declare their reliable cache period in their Capability Statement . 3.4.1.5.1 Raw XML Example: Consequence ( canonical form In the first example, a Clinical EHR issues an order for a particular imaging examination to be performed on a patient. This is considered to be a message of Consequence : multiple orders should not be created (in practice there are usually human review processes that catch multiple orders, but repeat orders create entropy in the system that is harmful). The EHR sends a message where the Bundle.id is UUID 1 (72edc4e0-6708-42ab-9734-f56721882c10), with a MessageHeader.id of UUID 2 (dad53a57-dcb4-4f18-b066-7239eb4b5229). The EHR system never receives a response to the message; it does not know whether the request message got lost, or the imaging management systems was unable to process the request, or whether it successfully processed the message and the response was lost. In this case, the EHR system resends the message with same two identifiers. In this case, the imaging system successfully received the message, and processed it. Because it receives the resent order after 1 minute (which is within its 15 minute cache time), and the two UUIDs 1 and 2 match a message it has already processed, it knows that it already processed the order, and simply returns the previous response. In the case of additional resent queries, the application keeps sending the original response, though it may + also alert system administrators that the same original message keeps being resent, since lost messages should be a rare occurrence. When the EHR system finally receives the message, it knows how the imaging management system responded; it can be sure because the message id from the original request is echoed in the response portion of the returned message. 3.4.1.5.2 Example: Currency In this second example, a Clinical EHR needs to know what appointment slots are available for a particular imaging procedure. This is a message of Currency : available slots are ever disappearing, and ordering a slot that has become unavailable is a waste of time for the humans and systems involved. The EHR sends a message where the Bundle.id is UUID 3 (4c7f5cb2-5964-4d42-b719-e0227461818c), with a MessageHeader.id is UUID 4 (63ed7d68-b2cc-421d-ba1c-a6c7785581f2). The EHR system never receives a response to the message; it does not know whether the request message got lost, or the imaging management systems was unable to process the request, or whether it successfully processed the message and the response was lost. In this case, the EHR system resends the message with same MessageHeader.id (UUID 4), but creates a new Bundle.id (c7c17fe4-9560-49c7-b2ae-42636476fb86). In this case, the imaging system successfully received the message, and processed it. When it receives the resent order after 1 minute (which is within its 15 minute cache time), it sees that although the message id is the same, the Bundle.id has changed, and it reprocesses the message again, and sends a new response. When the EHR system finally receives the message, it knows the current slot availability on the imaging management system responded. Note that the existence of active intermediaries (or "middleware") creates the need for this protocol - the original sender matches the response to the request based on the MessageHeader.id, and so an active intermediary that choose the re-initiate a query that it previously relayed cannot change the MessageHeader.id. This protocol avoids the need for the MessageHeader.id to change, and only requires change to the Bundle.id which is never the basis for context linking outside the immediate message exchange protocol described here. 3.4.2 Capability Statement Applications may only assert conformance to "FHIR messaging" if they publish a Capability statement see XML Format Specification so the claim may be verified. A Capability statement lists all the message events supported (either as sender or receiver) and for each event, a profile that states which resources are bundled (sender), or are required to be bundled (receiver), and any rules about the information content of the individual resources. )

3.4.3 $process-message

The simplest way to handle messages where there are also RESTful interactions occurring is to use the $process-message . This operation accepts a message, processes it according to the definition of the event in the message header, and returns a one or more response messages. See the opreation definition for further details. PatRelatedPerson

<?xml version="1.0" encoding="UTF-8"?>

<StructureDefinition xmlns="http://hl7.org/fhir">
  <id value="patient-relatedPerson"/> 
  <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-wg">
    <valueCode value="pa"/> 
  </extension> 
  <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm">
    <valueInteger value="1"/> 
  </extension> 
  <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status">
    <valueCode value="trial-use"/> 
  </extension> 
  <url value="http://hl7.org/fhir/StructureDefinition/patient-relatedPerson"/> 
  <identifier> 
    <system value="urn:ietf:rfc:3986"/> 
    <value value="urn:oid:2.16.840.1.113883.4.642.5.1337"/> 
  </identifier> 
  <version value="5.0.0-snapshot3"/> 
  <name value="PatRelatedPerson"/> 
  <title value="Patient Related Person"/> 
  <status value="draft"/> 
  <experimental value="false"/> 
  <date value="2020-12-28T16:55:11+11:00"/> 
  <publisher value="HL7"/> 
  <description value="In some cases a Patient.contact will also be populated as a RelatedPerson resource.

   This linkage permits the linkage between the 2 resources to be able to accurately
   indicate a representation of the same individual, and updating details between
   could be appropriate."/> 
  <fhirVersion value="5.0.0"/> 
  <mapping> 
    <identity value="rim"/> 
    <uri value="http://hl7.org/v3"/> 
    <name value="RIM Mapping"/> 
  </mapping> 
  <kind value="complex-type"/> 
  <abstract value="false"/> 
  <context> 
    <type value="element"/> 
    <expression value="Patient.contact"/> 
  </context> 
  <type value="Extension"/> 
  <baseDefinition value="http://hl7.org/fhir/StructureDefinition/Extension"/> 
  <derivation value="constraint"/> 
  <snapshot> 
    <element id="Extension">
      <path value="Extension"/> 
      <short value="This contact may have further details in this RelatedPerson"/> 
      <definition value="In some cases a Patient.contact will also be populated as a RelatedPerson resource.

       This linkage permits the linkage between the 2 resources to be able to accurately
       indicate a representation of the same individual, and updating details between
       could be appropriate."/> 
      <min value="0"/> 
      <max value="*"/> 
      <base> 
        <path value="Extension"/> 
        <min value="0"/> 
        <max value="*"/> 
      </base> 
      <constraint> 
        <key value="ele-1"/> 
        <severity value="error"/> 
        <human value="All FHIR elements must have a @value or children"/> 
        <expression value="hasValue() or (children().count() &gt; id.count())"/> 
        <source value="http://hl7.org/fhir/StructureDefinition/Element"/> 
      </constraint> 
      <constraint> 
        <key value="ext-1"/> 
        <severity value="error"/> 
        <human value="Must have either extensions or value[x], not both"/> 
        <expression value="extension.exists() != value.exists()"/> 
        <source value="http://hl7.org/fhir/StructureDefinition/Extension"/> 
      </constraint> 
      <isModifier value="false"/> 
    </element> 
    <element id="Extension.id">
      <path value="Extension.id"/> 
      <representation value="xmlAttr"/> 
      <short value="Unique id for inter-element referencing"/> 
      <definition value="Unique id for the element within a resource (for internal references). This may

       be any string value that does not contain spaces."/> 
      <min value="0"/> 
      <max value="1"/> 
      <base> 
        <path value="Element.id"/> 
        <min value="0"/> 
        <max value="1"/> 
      </base> 
      <type> 
        <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type">
          <valueUrl value="id"/> 
        </extension> 
        <code value="http://hl7.org/fhirpath/System.String"/> 
      </type> 
      <isModifier value="false"/> 
      <isSummary value="false"/> 
      <mapping> 
        <identity value="rim"/> 
        <map value="n/a"/> 
      </mapping> 
    </element> 
    <element id="Extension.extension">
      <path value="Extension.extension"/> 
      <slicing> 
        <discriminator> 
          <type value="value"/> 
          <path value="url"/> 
        </discriminator> 
        <description value="Extensions are always sliced by (at least) url"/> 
        <rules value="open"/> 
      </slicing> 
      <short value="Extension"/> 
      <definition value="An Extension"/> 
      <min value="0"/> 
      <max value="0"/> 
      <base> 
        <path value="Element.extension"/> 
        <min value="0"/> 
        <max value="*"/> 
      </base> 
      <type> 
        <code value="Extension"/> 
      </type> 
      <constraint> 
        <key value="ele-1"/> 
        <severity value="error"/> 
        <human value="All FHIR elements must have a @value or children"/> 
        <expression value="hasValue() or (children().count() &gt; id.count())"/> 
        <source value="http://hl7.org/fhir/StructureDefinition/Element"/> 
      </constraint> 
      <constraint> 
        <key value="ext-1"/> 
        <severity value="error"/> 
        <human value="Must have either extensions or value[x], not both"/> 
        <expression value="extension.exists() != value.exists()"/> 
        <source value="http://hl7.org/fhir/StructureDefinition/Extension"/> 
      </constraint> 
      <isModifier value="false"/> 
      <isSummary value="false"/> 
    </element> 
    <element id="Extension.url">
      <path value="Extension.url"/> 
      <representation value="xmlAttr"/> 
      <short value="identifies the meaning of the extension"/> 
      <definition value="Source of the definition for the extension code - a logical name or a URL."/> 
      <comment value="The definition may point directly to a computable or human-readable definition

       of the extensibility codes, or it may be a logical URI as declared in some other
       specification. The definition SHALL be a URI for the Structure Definition defining
       the extension."/> 
      <min value="1"/> 
      <max value="1"/> 
      <base> 
        <path value="Extension.url"/> 
        <min value="1"/> 
        <max value="1"/> 
      </base> 
      <type> 
        <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type">
          <valueUrl value="uri"/> 
        </extension> 
        <code value="http://hl7.org/fhirpath/System.String"/> 
      </type> 
      <fixedUri value="http://hl7.org/fhir/StructureDefinition/patient-relatedPerson"/> 
      <isModifier value="false"/> 
      <isSummary value="false"/> 
      <mapping> 
        <identity value="rim"/> 
        <map value="N/A"/> 
      </mapping> 
    </element> 
    <element id="Extension.value[x]">
      <path value="Extension.value[x]"/> 
      <short value="Value of extension"/> 
      <definition value="Value of extension - must be one of a constrained set of the data types (see [Extensibility](

      extensibility.html) for a list)."/> 
      <min value="1"/> 
      <max value="1"/> 
      <base> 
        <path value="Extension.value[x]"/> 
        <min value="0"/> 
        <max value="1"/> 
      </base> 
      <type> 
        <code value="Reference"/> 
        <targetProfile value="http://hl7.org/fhir/StructureDefinition/RelatedPerson"/> 
      </type> 
      <constraint> 
        <key value="ele-1"/> 
        <severity value="error"/> 
        <human value="All FHIR elements must have a @value or children"/> 
        <expression value="hasValue() or (children().count() &gt; id.count())"/> 
        <source value="http://hl7.org/fhir/StructureDefinition/Element"/> 
      </constraint> 
      <isModifier value="false"/> 
      <isSummary value="false"/> 
      <mapping> 
        <identity value="rim"/> 
        <map value="N/A"/> 
      </mapping> 
    </element> 
  </snapshot> 
  <differential> 
    <element id="Extension">
      <path value="Extension"/> 
      <short value="This contact may have further details in this RelatedPerson"/> 
      <definition value="In some cases a Patient.contact will also be populated as a RelatedPerson resource.

       This linkage permits the linkage between the 2 resources to be able to accurately
       indicate a representation of the same individual, and updating details between
       could be appropriate."/> 
      <min value="0"/> 
      <max value="*"/> 
    </element> 
    <element id="Extension.extension">
      <path value="Extension.extension"/> 
      <max value="0"/> 
    </element> 
    <element id="Extension.url">
      <path value="Extension.url"/> 
      <fixedUri value="http://hl7.org/fhir/StructureDefinition/patient-relatedPerson"/> 
    </element> 
    <element id="Extension.value[x]">
      <path value="Extension.value[x]"/> 
      <min value="1"/> 
      <type> 
        <code value="Reference"/> 
        <targetProfile value="http://hl7.org/fhir/StructureDefinition/RelatedPerson"/> 
      </type> 
    </element> 
  </differential> 


</

StructureDefinition


3.4.4

>


Relationship
between
Messaging
and
REST



As
well
as
this
messaging
framework
documented
here,
FHIR
also
defines
a
RESTful
API
.
The
messaging
and
RESTful
frameworks
are
related
in
that
both
share
the
same
set
of
resources
on
which
they
operate.
In
fact,
the
basic
MessageHeader
resource
that
the
messaging
framework
is
implemented
is
itself
a
resource
that
can
treated
in
a
RESTful
approach.
The
kinds
of
functionality
that
the
RESTful
API
and
the
messaging
framework
offer
are
very
similar;
their
primary
difference
is
architectural
in
nature.

For instance, the messaging framework defines an event for notifying that an administration resource Usage note: every effort has been created or updated; the REST API offers similar services ( history and Subscription ). On the other hand, there are differences in the capabilities offered - while a patient merge can be implemented as a series of RESTful operations performed by the client that update all resources linked to the patient, when a message command to merge patient records is processed, the server will do all the work, and is also able made to merge in areas not exposed on the RESTful API. The REST API, however, provides a set of basic operations on all resources ensure that would need special definitions in the messaging framework - definitions that examples are not provided. There is no expectation that RESTful systems will need to offer messaging support, or vice versa, though systems may find it useful to support both sets of functionality in order to satisfy a wider range of implementers. As a resource that can be used with the RESTful framework, the MessageHeader resource has the normal resource end-point (/MessageHeader), which is used to manage a set of static message resources. This could be used to make an archive of past messages available. Creating or updating MessageHeader resources in this fashion does not represent the actual occurrence of any event, nor can it trigger any logic associated with the actual event. It is just for managing a set of message header resources. 3.4.4.1 Asynchronous Messaging using the RESTful API It is possible to exchange messages using the RESTful end-point as a central point of exchange. This is not particularly efficient compared to other methods, but is useful for low-volume asynchronous exchange. To send a message, a sender posts the message bundle to the /Bundle end-point, with a uri that identifies the receiver at MessageHeader.destination.endpoint . The RESTful server accepts the bundle, stores it as a single bundle, and indexes it on the MessageHeader . To receive messages, a receiver searches for all messages destined for itself, since its last check: GET [base]/Bundle?message.destination-uri=[rcv]&_lastUpdated=>2015-03-01T02:00:02+01:00 The receiver works through the response, processing each message. As each message is processed, the receiver creates a response message, reversing the source and destination, correct and posts it back to the server. To check for responses, the original sender searches for response messages destined for itself, since its last check: GET [base]/Bundle?message.destination-uri=[snd]&message.response-id:missing=false &_lastUpdated=>2015-03-03T06:03:522+01:00 This lightweight protocol needs ongoing administration to ensure that multiple parties do not interfere with each other by re-using the same system identifier (and against malicious attack). 3.4.5 Defining Events The message.code element carries a Coding that identifies the event that the message conveys. Events may be defined using the MessageDefinition resource. This specification does not define any events, useful, but may do so in the future if implementers find this useful. 3.4.6 Invoking Operations via Messages A message can be used to invoke an operation as defined for a RESTful interface using an operation definition. To invoke an operation using a message: The requester sends a message (a bundle with type = message, and a message header resource) The message header has an event.system of urn:ietf:rfc:3986 The event.code is the URL from the operation definition OperationDefinition.url The MessageHeader.data refers to a Parameters resource The parameters resource is populated appropriately as specified by the nominated operation definition The recipient executes the operation as specified, and then: The receiver sends a message (a bundle with type = message, and a message header resource) The message header has the same event as the original message The MessageHeader contains a response that refers to the original request message, and a code for the outcome, with details if the operation failed The MessageHeader.data refers to a Parameters resource The parameters resource is populated appropriately as specified for the response by the nominated operation definition If the operation definition specifies a single return, then this is returned as the target of the MesssageHeader.data directly Here's an example: <Bundle xmlns="http://hl7.org/fhir"> <id value="urn:uuid:77831928-2a35-4c08-9496-8232323bf48c"/> <!-- normal bundle stuff --> <entry> <fullUrl value="urn:uuid:6080d4a7-5e05-45dc-96d5-f75329564d1f"/> <resource> <MessageHeader> <id value="cac8143e-6138-4f45-b086-bb8ebf976aae"> <!-- normal message header stuff --> <event> <system value="urn:ietf:rfc:3986"/> <!-- value set expansion --> <code value="http://hl7.org/fhir/OperationDefinition/ValueSet-expand"/> </event> <!-- more normal message header stuff --> <data> <reference value="urn:uuid:00213637-dc7c-40d2-a7de-f4ef1eea5685"/> </data> </MessageHeader> </resource> </entry> <entry> <fullUrl value="urn:uuid:00213637-dc7c-40d2-a7de-f4ef1eea5685"/> <resource> <Parameters> <parameter> <name value="identifier"/> <valueUri value="http://hl7.org/fhir/ValueSet/identifier-type"/> </parameter> </Parameters> </resource> </entry> </Bundle> Note that there's no way to anchor the execution of the operation against a URL. The only operations that can be executed in this way they are defined to be executed at the System or Resource level for a particular resource. 3.4.6.1 Invoking Search via Messages In the same way that a defined operation can be invoked, a regular search operation can be invoked. This also uses the Parameters resource, with the following rules: The event code is "search-type" or "search-system" in the system http://hl7.org/fhir/restful-interaction If the event type is "search-type" there SHALL be not a parameter "resourceType" with specifies the type normative part of resource being searched The search parameters are converted to FHIR data types according to the following table Search Parameter Type Data Type number integer date dateTime string string token string or Coding (split the system and code apart) reference uri composite string quantity string or Quantity (split the syntax out) uri uri Here's an example: specification.

<Bundle xmlns="http://hl7.org/fhir"> <id value="urn:uuid:77831928-2a35-4c08-9496-8232323bf48c"/> <!-- normal bundle stuff --> <entry> <fullUrl value="urn:uuid:c466754c-09c0-4f59-9f76-a48bd0ea27c9"/> <resource> <MessageHeader> <!-- normal message header stuff --> <event> <system value="http://hl7.org/fhir/restful-interaction"/> <!-- Search against Patient --> <code value="search-type"/> </event> <!-- more normal message header stuff --> <data> <reference value="urn:uuid:59a17a19-46eb-42d9-821a-f93a0c530cac"/> </data> </MessageHeader> </resource> </entry> <entry> <fullUrl value="urn:uuid:59a17a19-46eb-42d9-821a-f93a0c530cac"/> <resource> <Parameters> <parameter> <name value="resourceType"/> <valueString value="Patient"/> </parameter> <parameter> <name value="gender"/> <valueString value="m"/> </parameter> </Parameters> </resource> </entry> </Bundle>