FHIR and XDS – Submitting a document from a Document Source

This post will focus on the XDS Document Source actor and the mechanics behind submitting a document and its metadata to an XDS system. But before we do that, we need to review some aspects of the way that’s going to work in our RESTful context.

We’ll use the DocumentReference to record the metadata, but one of the tricky bits is going to be managing the ‘entity identifiers’ – particularly for patient, practitioner and organisation that XDS needs, vs the resource ID that FHIR requires for references.

A bit of background.

An Identifier is something that identifies an object or identity – like a patient. It has a number of properties, of which the most relevant to this discussion are the system and the value.

The system is the namespace within which the value is unique. A single entity/patient can potentially have many different identifiers – for example a patient might have:

  • An identity within a national identity service
  • An identity in their local doctors system
  • A drivers license
  • A library card

and so on. It is also possible that a single person could accidentally have multiple identifiers in the same system – for example when an administrator creates a new identifier for a patient without first checking whether they already have one. In fact one of the jobs of the identity service is to locate these duplicates and merge them, but I digress…

IHE recommends that the participants agree in advance on which identifier systems will be used in XDS, and provides a profile called the PIX profile (Patient Identity Cross reference) that describes how to manage and cross reference these identifiers – so that if you have one identifier you can get the matching ones for that patient. There is another query – PDQ – or Patient Demographic Query that describes how to query a registry using name, Date of Birth and other demographics and get back a list of patients – including known identifiers. Often, a single system will implement both of these profiles – and the term PIX/PDQ to describe them is not uncommon.

But when a Document Source submits a document to a repository using FHIR, it needs a resource reference to the patient – which is a URI to the patient resource – not an identifier.

This is a problem for a client that only has an identifier for a patient.

Reviewing what PIX/PDQ does, this all seems suspiciously like queries against the FHIR Patient resource. If we imagine that there is a server that exposes a /Patient endpoint and is backed up by all the identity matching and update functionality of an identity registry, then queries against this endpoint will perform much the same functionality as PIX/PDQ queries – for example:

  • GET /Patient?name=power&gender=M      (PDQ-ish)
  • GET /Patient?identifier=PRP1660                   (PIX-ish)

would both return a list of matching patients, each of which would contain all the identifiers known for a patient. We can even ask for previous versions of the resource if we need them, and Patient resources can link to merged resources using the link property. This is actually what we discussed in an earlier post, though we didn’t really talk about merging and linking patients (a topic for another post perhaps).

So – provided that we have such a server (which is kind of fulfilling the role of Identity Source in XDS) then we have our ‘identifier lookup’ sorted. But we’re still not quite there. Who should do this lookup?

There are a couple of options:

  • We could off load the problem to the repository – require it to be able to receive an identifier, query the /Patient server using that identifier and get the resource ID. There’s even a way of doing that using a bundle in FHIR (part of transaction processing)  – but this has the limitation that it only works on the same server as the search, which would mean duplicating patient data on all repositories. That doesn’t really sound right.
  • We could require that the Document Source perform that lookup, and include the full FHIR reference in the submission.

Although we are asking the Document Source to perform more work, this does place the responsibility for correctly identifying the patient on the Document Source, which feels like the right place. We will go with this solution, so the updated diagram now shows a line between the Document Source and the Identity Source, indicating that lookup.

Updated FHIR XDS

Similar issues exist for the Practitioner (author) and the Organisation (custodian), and we will adopt the same attitude – i.e. that it is the responsibility of the Document Source to locate the required resource ID. Fortunately, it’s a bit easier for these two as it’s not so critical to absolutely identify them (in a FHIR sense). If we can’t do that, then we can use FHIRs ability to contain an unidentified resource within the DocumentReference resource (and, in fact, it was this issue that led to the concept of contained resources in the first place, early on in FHIR’s evolution). There are, of course down-sides to this approach – but sometimes it’s the only way.

A couple of notes:

  • Astute readers will note that the DocumentReference resource can have subjects other than Patient. We’re not thinking about them at the moment, but if/when we do then the same rule will apply – the Source needs to specify the resource ID – i.e. identify the resource.
  • We do have the option of creating a custom Web Service (could be REST or SOAP) on the repository that performs the lookup – i.e. takes an identity and performs the query on the appropriate server on behalf of the source. We’d want to carefully think through the implications of that approach.
  • Having a copy of the Patient resources on the repository and using the bundle search facility to create local ID’s remains an option – after all from the perspective of XDS it is the identifiers we are after. It doesn’t feel right to me, but those more expert in REST than I might have a different opinion.

So we have our identifiers and ID’s sorted – now to submit the document! This is going to involve updating both the repository and the registry – in other words a transaction. As always, there are a number of options:

  • The Document Source could send the document to the repository – getting back an ID (or in some other way having a URI that allows a consumer to retrieve it), and then create and send a DocumentReference resource to the registry. This is a perfectly legitimate approach – and is required in some situations such as a non-FHIR repository – but it does mean that the client needs to manage the transaction, as we discussed with medications. That may or may not be an issue.
  • We could use FHIRs transaction functionality to off load the responsibility to the Repository Server.

The rest of this post will describe the second approach.

The steps we need to follow are:

  1. Create a new bundle
  2. Get the document we want to store, base-64 encode it, and save it in a bundle as a Binary resource
  3. Create the DocumentReference resource and place that in the bundle
  4. Send the bundle to the repository root
  5. Process the response (succeed or fail)

1. Create a bundle

This is a simple matter of creating the basic structure of the bundle.

2. Get the document.

Retrieve the document from whatever local store it is help in, base 64 encode it, and create an entry for it in the bundle using the binary resource. Its ID should be a cid: ID so that the repository server knows to create a new resource (i.e. treat it as a create operation).

3. Create the DocumentReference resource

This is where the work is. The DocumentReference resource contains all the metadata required for the document to be located via a query, and the contents will depend on what information is available and what is specified in the Affinity Domain (i.e. what are the valid options for each of the properties in the DocumentReference resource).

In addition, the ‘generic’ DocumentReference resource has been profiled specifically to suit the XDS requirements. It’s going to take a while to go over the details of this, so we’ll hold that discussion over until we’ve finished the mechanics of transmission.

The DocumentReference resource will also contain the references to other resources we need, which may be:

  • A straightforward resource reference to the resource – e.g. the patient resource – on a server. There’s no need to include the resource in the bundle, though we can if we want to.
  • A contained resource if we were unable to resolve the link.

When complete, add the resource to the bundle.

(There may be other resources to include – like attachments to documents – that we can talk about some other time.)

4. Send the bundle to the server and process the response.

POST the bundle to the root of the Repository server, as we discussed in the post on medications. The server will perform the required processing which has the following steps:

  1. Save the document in the local store, which will generate an ID. It will subsequently by available by a query against the /Binary endpoint of the server – eg GET /Binary/{ID}
  2. Update the location property in the DocumentReference resource to the local URI
  3. POST the DocumentReference resource to the registry
  4. Return a response to the client.

Note that we are assuming that the repository is managing the transaction. If there are errors back from the registry (eg missing or invalid data) – then it should remove the document from the local store and return an error to the client (ideally with a OperationOutcome resource).

Note also that the above processing – ie that the server should manage bundles containing DocumentReference and Binary resources by POSTing the DocumentReference to a configured Registry Server is one that depends on local policy and configuration. It may be clearer to create a custom endpoint to make this processing explicit.

There are other processing options for the server (eg asynchronous processing) – again, something to be discussed in a later post.

5. Process the response

The HTTP status code will indicate success or failure, and in the event of a failure then the server should return an OperationOutcome  resource with details.

So, we have finally saved a document in the repository and updated the registry. We didn’t have the space available to talk about the DocumentReference resource in any detail, and it’s kind of important to know what to put in there, so in the next post we’ll talk about that resource (and touch on the DocumentManifest), after which we can start to think about the consumer.

About David Hay
I'm an independent contractor working with a number of Organizations in the health IT space. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the FHIR standard. I'm the author of a FHIR training and design tool - clinFHIR - which is sponsored by InterSystems Ltd.

5 Responses to FHIR and XDS – Submitting a document from a Document Source

  1. Pingback: The FHIR DocumentReference resource | Hay on FHIR

  2. Pingback: Getting documents from a #FHIR XDS infrastructure | Hay on FHIR

  3. Pingback: #FHIR XDS – updating a document | Hay on FHIR

  4. Pingback: Question: Exchanging CDA « Health Intersections Pty Ltd

  5. Pingback: Creating a #FHIR document for the January Connectathon | Hay on FHIR

Leave a Reply

%d bloggers like this: