This document describes some of the considerations related to the potential introduction of a fhirVersion element, at least for pre-normative FHIR instances. Content highlighted in yellow identifies places where changes to the FHIR spec may be needed.

General

●“Prior to Normative” means prior to all resources a given server supports being published as normative and locked into backward compatibility

●For most servers this is at least 5 years away, and for some could easily be 10

○And even when ‘normative’ for a given space exists, interacting with older systems will happen for 5-10 years longer than that.

●Even when normative, new non-modifier elements and new codes can be introduced, meaning that any system with strict schema validation may not be able to validate/support newer versions.

●Our objective for normative FHIR is to be versionless, like DICOM. I.e. systems process elements they recognize and safely ignore elements[1][2] they don’t - and where the specification can theoretically change every 3-4 weeks and the implementer community doesn’t care because an implementation based on the spec from 3 years ago can seamlessly interoperate with an implementation based on the spec from yesterday[3][4]

○I.e. There should be no configuration and no analysis required to make the decision to support interoperating [5][6][7][8]with a system that supports a different (normative) version of FHIR than you do.

○The rationale for being versionless is that the presence of versions tends to be a barrier to interoperability[9][10] - systems will refuse to accept data that declares a version other than the version(s) the receiving system explicitly supports. And so analysis and code changes are required every time a new version comes out to allow adding of the new versions to the set of “safe” versions for that system. In some cases, this results in significant delay and/or costs. E.g. “We don’t support HL7 2.8 in that release of our product, you need to update - which will cost $100k and take 6 months” - even though the data accepted by the system might not have changed since 2.3.1…

●Primary focus on supporting versions is for “official” releases - i.e. DSTU1, DSTU2, STU3, R4. However, implementers often have systems that are tied to interim releases. These are usually connectathon/ballot versions. But on occasion, implementations may also be tied to specific continuous integration versions. The policy will need to support such variations

●From time to time, HL7 may update an existing release with a technical correction. Such changes are never substantive and are never breaking changes. As such, there should be no need for a system to know whether or what technical correction release was used.

●We don’t want to get into a situation where a single FHIR instance contains mixed versions - so all resources in a Bundle, in a Parameters instance or sent as contained resource must be the same version as the root instance. Systems incorporating data from multiple sources may need to perform FHIR version conversions when combining data.

REST

●If using REST, you can query the FHIR version by querying the Conformance or CapabilityStatement instance for the endpoint

●This presumes that each endpoint only supports one release of FHIR. Does anyone have a use-case for us supporting multiple versions of FHIR on a single RESTful endpoint?[11][12]

○The question indicates that the assumption is that the API itself doesn’t change, just the contents of the resource. But that’s not true - the API itself changes, and any version strategy needs to be aware of that

●In theory, an endpoint can switch from one version of FHIR to a new version of FHIR but remain at the same URL

○Systems could theoretically query the Conformance/CapabilityStatement before every operation, but that’s not practical - and in theory, the change could come between retrieval of the FHIR version and subsequent execution

○In practice, a process of trying to execute the operation and, if it fails as “non-valid”, then querying the Conformance/CapabilityStatement to see if the version has changed is most appropriate

○In some cases, data submitted against the old version may be valid against the new version. In this case, the change in version wouldn’t be detected. This can have negative consequences in two circumstances

■The client system might be able to communicate more/better/more accurate information using the newer FHIR interface than the older FHIR interface. This isn’t a serious problem though because obviously [13][14][15]business needs were still being met with the old interface. And so long as the Conformance/CapabilityStatement is queried with sufficient regularity (once a week, once a day, once an hour - as deemed appropriate by the Client), the period of time this issue would persist is minimal

■The meaning of an element or code may have changed between one version and the next, but the name has remained the same. I’m not aware of this having happened[16][17][18], but I’m also not aware of any prohibition on this happening. And if it did happen, it’d be hard to detect without detailed study of the spec - I expect our conversion/mapping routines presume equivalent meaning. How do we check our existing STU1 and STU2 elements? Should we have a policy that ensures this doesn’t happen moving towards R4?

Documents

●When processing a document, there’s not necessarily a Conformance/CapabilityStatement instance to look at. E.g. The document may just show up as an email attachment. As such, there’s no way to know what version of FHIR a given document was created with.

●Systems can use an approach of “try with the newest version supported, and if that fails, try with the next oldest. This approach becomes less feasible the larger the number of candidate versions supported and even with only a few versions can be prohibitively expensive.

●Defining a fhirVersion in Bundle as a standard extension for use until we’re normative seems reasonable?

●If such an extension were introduced, it could have conformance language such as the following: “This extension SHALL NOT be used on documents where all resources in the Bundle are normative” - this would ensure migration to versionless behavior once resources are normative.[19][20][21][22][23]

Messages

●If a message server is RESTful, the REST approach of looking at the Conformance/CapabilityStatement to determine what version is being sent is will work (same caveats apply[24][25][26][27][28][29]).

●However, FHIR messages can be sent in situations where no REST interface exists - using SOAP, MMLP or a variety of other transport mechanisms. And such messages may run through multiple endpoints between origin and target system.

●In theory, this can be managed by saying that the endpoint address must be different for a given recipient for each version of FHIR and that the address for each hop in the message delivery path must also be different for each version of FHIR supported.

●The parsing behavior of a routing endpoint could theoretically need to change for each version supported as the MessageHeader or Bundle resource or the underlying syntax could change between releases prior to normative. However, in practice, this is an uncommon impact.[30][31]

●Such behavior is contrary to the way message delivery systems have historically been architected. It may result in a significant proliferation of delivery addresses for messages that support many versions of FHIR, including interim versions. Is this acceptable or do we need a fhirVersion extension on MessageHeader for use during the prior-to-normative phase?

●Similar language conformance language could be used as was proposed for documents if such an extension were added.

Services

●If servers are making use of operations on a RESTful interface, the REST approach of looking at the Conformance/CapabilityStatement to determine what version is being sent is will work (same caveats apply).

●However, services can also be invoked using SOAP or other means, meaning there might not be a Conformance/CapabilityStatement to access.

●Similar issues arise here as for messaging, though typically there isn’t multi-hop delivery, so the cost of separate endpoints per FHIR version is less.

●Services do not use the Bundle resource, so if version declaration were to be supported, the fhirVersion extension would also need to be supported on the Parameters resource. Is this needed?

●Similar language conformance language could be used as was proposed for documents if such an extension were added.

Persistence and post-endpoint processing

●Systems that provide multiple endpoints to support different versions of FHIR will likely still have a single set of business logic and a single persistence layer. In some cases, knowledge of the FHIR version may still be relevant (e.g. if persisting a FHIR document “as is” to ensure signature validity)

●The FHIR specification does not address how data is persisted nor what data is maintained behind the front door. Other information such as authorization tokens and other header information will likely need to be propagated as well. There is no need to define a standard structure to handle this.

2017-05-06 Madrid Connectathon hot topic discussion

Possible options for version declaration

  1. mime type (doesn't work for persistence)
  2. extension (works w/ DSTU1/2, suggests non-long-term)
  3. profile declaration with non-canonical URL (harder to extract)
  4. profile declaration with canonical URL + version (not declared for DSTU1/2)
  5. tag (works w/ DSTU1/2)
  6. new element for meta (doesn't work for dstu1/2)

E.g.

Content-type: application/fhir+xml?version=3.0

<Basic xmlns="

<meta>

<extension url="

<valueCode value="3.0"/>

</extension>

<fhirVersion value="3.0"/>

<profile value="

<profile value="

<tag>

<system value="

<code value="3.0"/>

</tag>

</meta>

</Basic>

No consensus on any of these options - or even adding version at all. Will revisit after doing the following:

●Grahame will write up a description of "tightly managed interfaces" - what capabilities FHIR has and what tradeoffs/risks exist

Additional comments

Possible additional assertions for the spec to help mitigate impact of adding version to spec:

●The version number SHALL only change if the serialization or interpretation of data has changed between versions (essentially 3.0.0, 3.0.1, 3.0.2 would all be 3.0 as no substantive changes can have occurred)

●Implementations that support any normative FHIR version of a resource SHALL transparently process (no upgrade/configuration change) instances that declare newer FHIR versions if their CapabilityStatement declares acceptUnknown=elements or both.

[1]For an EHR that needs to assess clinical data elements, or analytics for population health or quality report, how can it be possible to determine what is "safe" to ignore without strong effective version management?

[2]In FHIR, everything can be ignored in some cases - even modifier elements so long as you understand their impact and decide you don't care. In any case, we have strong effective version management. What we don't have is version declaration - those are different things.

[3]In theory the approach of making FHIR versionless is a good one, however in practice I expect many implementers will create a new REST web service endpoint for each version over concerns about the risk of inadvertently breaking client applications. If we provide an endpoint that initially implements STU4, and then update it to STU5, and that causes an application written by one of our customers to fail then we won’t look good even if the root cause is a defect in the customer’s application. No one wants to have to explain the nuances of blame to our senior business leaders.

[4]Reality is that any change to the interface - adding support for a new code, sending a new extension, changing the sort order of elements where sort order doesn't matter, etc. could break a client system. The types of changes allowed between FHIR versions is very restricted, so an application would have to be pretty fragile to be affected. It's possible some systems might continue to create new endpoints. But if there's distinct endpoints, there's still no need for declaring version in the instances.

[5]In the US Realm, the legal environment of HIPAA, FDA clearance on categories of medical software and wrongful death lawsuits means that large payers, large health systems and vendor must be capable and prepared to go into court with clear proof that software changes were reviewed and analyzed for impact on processing and operation. It is unclear how this operational reality can be managed without version management.

[6]If the new version of the specification adds 20 new data elements that you ignore and the spec says that, without prior business agreement, receivers are free to ignore those elements, you should be fine. We don't want a situation where systems refuse to accept new versions of normative content purely on the basis that they haven't reviewed what new (ignorable) data might be present.

[7]Less worried about new data elements; more worried about changes in cardinality. We're still dealing with latent fallout from HumanName.family being changed from an array to a string. People are going to build business logic based on these resources.

[8]Changing from an array to a string or vice versa is not something that would be allowed post-normative. So it's not something we'd need to worry about once we go totally versionless.

[9]GIven the dependency management challenges are large complex payer and provider backend systems, I make the case that versioning of FHIR APIs will be key to supporting interoperability. As authored by Tom Preston-Werner, inventor of Gravatars and cofounder of GitHub, it would seem that his approach for a Semantic Versioning specification should be strongly considered.

[10]FHIR APIs are versioned - that's what DSTU1, DSTU2, STU3, etc. are

[11]Not exactly - we use different endpoints over a shared store. Versioning becomes an issue at the persistence (and conversion) layer.

[12]Agree, but there's no need to standardize the persistence layer, right?

[13]not necessarily obvious in practice

[14]If the interface is left standing and the system can accept information over it, then it must meet business needs to some degree, though not as well as the new interface might?

[15]'must', only in an ideal world.

--

-----

/

/ +61 411 867 065

[16]that depends how narrowly we define this. We've had definition and domain value changes that have altered the intent and semantic range of elements

[17]Right. To the degree that sending Rn+1 data to an Rn system would cause harm?

[18]yes, if they were using said content

--

-----

/

/ +61 411 867 065

[19]There's other ways to do this

[20]Can you elaborate on the options?

[21]well, one is to use this:

<meta>

<profile value="

</meta>

--

-----

/

/ +61 411 867 065

[22]This is good!

[23]You can also have alternative encodings of the same content pointed at with independent DocumentReference, with a linkage (Transform) between the two. similar to

[24]Can a message header point at the capability statement from which the message is ejected?

[25]It could, but I'm not sure why you'd want to . . .

[26](It would have to be an extension)

[27]I was more suggesting it for discussion as a solution to the async nature. Not really wondering if it could be done today.

[28]Not sure what that adds above and beyond adding a fhirVersion to Bundle

[29]fair. no problem

[30]On what basis do you say that the parsing behavior for routing endpoint needing to change is an uncommon impact, for version changes in an API.

[31]None of these things have changed in a way that would have broken existing routers since DSTU1 was published