Craig Helfgott
Craig Helfgott

Reputation: 3

Trying to create multiple resources in a FHIR transaction

I am trying to create a Practitioner resource and an associated PractitionerRole resource as part of the same FHIR transaction, using conditional references. In my Practitioner resource, I put in a temporary identifier, identifier: [{ value: "foo" }]. In my PractitionerRole resource, I put in a conditional reference, practitioner: { reference: "Practitioner?identifier=foo" }. Then my transaction bundle looks like

const requestBundle = {
  resourceType: "Bundle",
  type: "transaction",
  entry: [
    {
      resource: practitionerResource,
      request: {
        method: "POST",
        url: "Practitioner",
      },
    },
    {
      resource: roleResource,
      request: {
        method: "POST",
        url: "PractitionerRole",
      },
    },
  ],
}

On running the transaction, I get the following error: Could not create FHIR record: Error resolving conditional reference: search 'Practitioner?identifier=foo' returned no results. Any idea what is going on here? I'm using the LinuxForHealth FHIR server, which claims to support conditional references.

I expect this to just run, and create two linked resources. If I separate the transaction into two distinct API calls, the conditional reference runs fine. According to the FHIR spec, in a transaction bundle all POST interactions should be processed before any conditional references are resolved. Furthermore, according to the documentation

A transaction may include references from one resource to another in the bundle, including circular references where resources refer to each other. When the server assigns a new id to any resource in the bundle which has a POST method as part of the processing rules above, it SHALL also update any references to that resource in the same bundle as they are processed.

Upvotes: 0

Views: 964

Answers (1)

Nik Klassen
Nik Klassen

Reputation: 711

You are correct that the spec says that conditional references should be resolved last, but in practice I am not surprised that you found that a FHIR server doesn't operated in the way you expect. This is because conditional references may be resolved by a search backend, or the underlying database may not be operating in a way that it allows you to "read your writes". In both of these scenarios the server may not have fresh information to lookup the conditional reference when it does the resolution. One reason this is done is if a transaction fails all operations are supposed to be rolled back, if you write information to a search backend before the transaction finishes this rollback may not be possible.

That said, there is an easy alternative to do what you want. The common way to refer to another resource in a bundle is to use the fullUrl field. This allows you to directly refer to another resource in the bundle and have the FHIR server rewrite that reference for you (this is what you see in the part of the spec you quoted). This is also much faster than doing a lookup in the database or search backend to find the new resource (if that was supported). So you could change your bundle to

const requestBundle = {
  resourceType: "Bundle",
  type: "transaction",
  entry: [
    {
      fullUrl: "urn:uuid:1", // value doesn't matter
      resource: practitionerResource,
      request: {
        method: "POST",
        url: "Practitioner",
      }
    },
    {
      resource: {
        // ...
        practitioner: { reference: "urn:uuid:1" },
      },
      request: {
        method: "POST",
        url: "PractitionerRole",
      },
    },
  ],
}

Upvotes: 0

Related Questions