Use case for Transaction vs Message in a middleware system

I am developing a middleware system that will connect different EMR/EHR systems. The systems on “either end” do not necessarily implement FHIR interfaces, or even RESTful APIs. We are using FHIR strictly as an internal data format. One system “publishes” FHIR-compliant JSON, and another system “consumes” it.

Clearly, a Bundle is the right structure to represent a set of data. For example, consider the following set of resources that represent a patient record:

  • Patient
  • Coverage for primary insurance
  • RelatedPerson to represent insured party
  • RelatedPerson to represent emergency contact
  • Organization to represent insurance company

Is a Message or Transaction is the best type of bundle for this purpose?

Message, probably. It kind of depends - transaction semantics are more narrowly nailed down.

@grahamegrieve I was leaning towards a message initially, but then I saw this sentence in the Bundle documentation: “Except for transactions and batches, Each entry in a Bundle must have a fullUrl which is the identity of the resource in the entry.” Since I am building a middleware system that passes messages between two non-FHIR systems, I don’t have a fullUrl to identify the resource on either system. I need to use relative references for all the resources. Can I use relative references in transactions and/or messages?

You can use urn:uuid:[someguid] as your fullURL if you assign GUIDs as the resource ids.

Thank you, @lloyd. I implemented your suggestion and I was able to get transactions to validate with relative references. Here is a short example, for future reference:

{
  "resourceType": "Bundle",
  "id": "bundle-transaction",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "urn:uuid:79378cb8-8f58-48e8-a5e8-60ac2755b671",
      "resource": {
        "resourceType": "Patient",
        "id": "patient1",
        "identifier": [
          {
            "type": {
              "coding": [
                {
                  "system": "http://hl7.org/fhir/v2/0203",
                  "code": "MR"
                }
              ],
              "text": "Medical Record Number"
            },
            "value": "abcd1234"
          }
        ],
        "name": [
          {
            "family": "Doe",
            "given": [
              "John",
              "Wayne"
            ],
            "suffix": "Jr."
          }
        ],
        "gender": "male",
        "birthDate": "1991-12-01",
        "address": [
          {
            "use": "home",
            "type": "postal",
            "line": "1234 South Orange Ave",
            "city": "Orlando",
            "state": "FL",
            "postalCode": "32812"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Patient"
      }
    },
    {
      "fullUrl": "urn:uuid:79378cb8-8f58-48e8-a5e8-60ac2755b674",
      "resource": {
        "resourceType": "Coverage",
        "id": "selfPay",
        "status": "active",
        "type": {
          "coding": [
            {
              "system": "http://hl7.org/fhir/coverage-selfpay",
              "code": "pay"
            }
          ]
        },
        "relationship": {
          "coding": [
            {
              "code": "self"
            }
          ]
        },
        "payor": [
          {
            "reference": "Patient/patient1"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Coverage"
      }
    }
  ]
}

That should work. You should also consider making the resource.id unique.