2

I have been successful in translating HL7 V2 messages to FHIR resources and POSTing them to a server. What has given me headaches however, is the question of how I can avoid creating duplicates during updates or accidential re-POST.

Example: I get a V2 ADT_A01 message with PID.#3 = 12345 so I create a patient ressource with identifier

  <identifier>
    <use value="usual"/>
    <label value="MRN"/>
    <system value="urn:oid:0.1.2.3.4.5.6.7"/>
    <value value="12345"/>
  </identifier>

and post it to the server. Identified by system and value the patient should be unique in any environment even if there are several systems feeding patients to the server.

Next I receive an ADT_A08 message and want to update my patient so I create another ressource with the same identifier as above but if I POST it to the server I will get two patients instead of one updated patient. Using PUT instead of POST is not an option, since PUT requires me to provide the patient's url which I don't know from the V2 message I am trying to process.

Ewout kindly referred me to the DSTU2 Transaction with conditional processing which allows me to put my Patient Resource in a Bundle and add a status "match" with a search property. e.g.

<Bundle xmlns="http://hl7.org/fhir" xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <id value="20141213205602" />
    <type value="transaction" />
    <base value="base" />
    <entry>
        <status value="match" />
        <search value="Patient?identifier=urn:oid:0.1.2.3.4.5.6.7|12345" />
        <resource>
            <Patient>
                <id value="myTempIDforInternalReferencingWithinTheBundle"/>
                <identifier>
                    <use value="usual" />
                    <label value="MRN" />
                    <system value="urn:oid:0.1.2.3.4.5.6.7" />
                    <value value="12345" />
                </identifier>...

The specification of the server side behaviour states: "If the search returns one match, the server uses this matching resource that already exists instead, and ignores the submitted resource." So this should prevent from accidentially creating the same patient twice. But since a positive match results in the server ignoring th provided data I am still left with no way to update my patient.

Of course, I could always run a query by identifier first and then update the returned ressource by it's ID. But since the server obviously does not treat the identifier as a unique constraint, I can never be sure that my search will yield exactly one result. So there would be human interaction required every time the server returns more than one result.

Long story short: What is the recommended procedure for systems knowing a patient by it's identifier but not by it's url to submit updates to a fhir server?

Best regards,

Simone

1 Answers1

2

This should work without the need for a transaction. A server should enforce uniqueness on your identifiers. As you said, you can query on the ID in the A08 and you should ALWAYS get back 0 or 1 in the response. If you don't, you're talking to a poorly implemented server.

And you also need to consider that consumers of a particular server may not even check this before deciding whether to create (POST) or update (PUT). They could treat all A01s AND A08s as creates. In my experience, I've seen streams from registration systems where these might arrive out of sequence. A client could reasonably send a create for an A08 if it finds no match on the ID, but a well-behaved client should also check for an existing resource when it gets an A01, too.

In any case, REST transactions are stateless and a server should be able to handle whatever a client sends its way.

In the scenario you describe, if you try to create a new Patient resource with the same ID, the server should detect that the resource already exists. And it should fail such a request with a conflict response (HTTP status 409) and in the OperationOutcome include a reason that states a Patient resource with that ID already exists, along with a URL to that resource. That would indicate to you that should try again, updating the referenced Patient resource with the data in your A08.

PeterB
  • 1,864
  • 1
  • 12
  • 9
  • 1
    Thanks Peter, this is pretty much the answer I was hoping to get :) However this particular server side behaviour is not described in the specification, right? Also, none of the public testing servers seems to be implemented in that manner. Or can anyone point me to a server that behaves as described above so I can test my client side implementation? – Simone Heckmann Dec 14 '14 at 17:39
  • 1
    The public test servers don't enforce uniqueness of identifiers; that's a business rule, and they are business rule free. I guess I could add something like that to my server, but it's also the sort of thing that creates testing surprises as well – Grahame Grieve Dec 14 '14 at 19:47
  • 1
    I think it would be great to have at least one server around that behaves the way Peter described. Teaching the client to try a POST first, parse the HTTP status and OperationOutcome and act accordingly by fetching the URL and try a PUT instead is certainly something the needs to be tested. But I don't know how to test if the servers accept everything I throw at them without complaint :) – Simone Heckmann Dec 14 '14 at 21:31
  • 1
    Peter's recommendation works out fine if there's just one Resource to submit, but an A08 message in most cases yields a whole bundle of Resources such as Patient, Encounter, Observation, Allergy... All of them need to be linked by their URL of which the client knows none. Using a transaction with transient identities would come in handy in this scenario and with the conditional processing I could also avoid creating duplicates. But processing an A08 message in this fashion would only allow adding new ressources but not updating the already existing ones which contradicts the semantics of A08. – Simone Heckmann Dec 15 '14 at 00:13
  • So I guess the only way to perform a "clean" update of all Resources affected by A08, the client needs to query the server for each Resource individually and replace the transient IDs in the bundle for the actual ones for every positive match. But then: What's the point of conditional processing? Wouldn't it be a lot more useful if Resources were updated instead of ignored in case of a positive match? That would make the above mentioned scenario A LOT easier to handle, client side, while adding no complexity to the server side implementation of conditional processing? – Simone Heckmann Dec 15 '14 at 00:13