Vermonster / fhir-kit-client

Node.js FHIR client library
MIT License
168 stars 36 forks source link

Support Returning Response Headers from FHIR Calls #181

Open jtilles-xealth opened 1 year ago

jtilles-xealth commented 1 year ago

Expected Behavior

Caller able to access response headers returned by a FHIR Server (e.g. Location Header returned from a Create Call which received a 201 success response). Verified response headers are received from server when making call via Postman, but unable to access via FHIR-Kit-Client

Actual Behavior

Caller unable to access response headers using FHIR-Kit-Client library.

Steps to Reproduce the Problem

  1. Call FHIR Server with valid create call (i.e. Observation.Create)
  2. Verify 201 status code received
  3. Attempt to access response header for Location. Response headers are unexpectedly empty

Specifications

Source of issue appears to be in the following file from ~L172-177 https://github.com/Vermonster/fhir-kit-client/blob/b13c62db10f89b09fa1687c19d54a1f8be7a2d7a/lib/http-client.js#L172

vstrateman commented 1 year ago

Hi @jtilles-xealth --

You should be able to access the headers with the method httpFor on the client object:

https://vermonster.github.io/fhir-kit-client/fhir-kit-client/1.9.1/module-fhir-kit-client-Client.html#.httpFor

Let us know if this solves your problem,

Vicki

jtilles-xealth commented 1 year ago

We tried playing around with this and found httpFor() from fhir-kit-client didn’t return headers. The screenshot showed the raw response object after calling httpFor , we renamed it responseFromFhirClient in the attached log. From what we can see, it only consists of {size, timeout} fields. This was after making a Patient.read call, per httpFor() documentation:

fhirClient.read({
  resourceType: 'Patient',
  id: 12345,
}).then((data) => {
  const { response: responseFromFhirClient, request: requestToFhirClient } = Client.httpFor(data)
  console.log(responseFromFhirClient)
})

We traced it back to where the raw response was returned from fetch call in fhir-kit-client: https://github.com/Vermonster/fhir-kit-client/blob/b13c62db10f89b09fa1687c19d54a1f8be7a2d7a/lib/http-client.js#L172. Basically, no status, nor headers in the response object returned from calling fetch method of cross-fetch module. One thing to note is that we use fhir-kit-client lib with a serverless lambda that makes calls to a fhir resource server. The data field of the above snippet did have patient resource. It’s just the raw response from fetch doesn’t have headers, nor status etc

image

Not sure if there is something we are missing here? We don’t even get the usual headers for a Patient Read call, such as ‘x-request-id’. For our actual use case, the exact header we are trying to get is returned from the EHR after making a Create call, where the EHR returns the FHIR ID of the created resource in the Location response header. Example from Postman call below: image

bkaney commented 1 year ago

@jtilles-xealth - here is a codesandbox that demonstrates it working with cerner's sandbox (see right-hand panel for output) https://bit.ly/3zwiiAK -- there was a problem with the types, so note this is using a new version I just published 1.9.2.

vstrateman commented 1 year ago

Closing due to lack of responses, reopen if needed

CHelfgott commented 1 year ago

I'd like to reopen this. My current code looks like the following:

      const newFhirPractitionerResponse = await this._fhirClient.create({
        resourceType: "Practitioner",
        body: fhirPractitionerBody,
        options: { headers: this._fhirHeaders },
      })
      const { response } = Client.httpFor(newFhirPractitionerResponse)

This works fine to e.g. extract resourceId from the location header when the request is successful, but when I've formatted my fhirPractitionerBody incorrectly (e.g. having an empty string in an address line), the create call, instead of returning the 400 response, throws an exception. I currently have encapsulated this in a try-catch, but I think it would be better if either the create call always returns the response from the server, or it throws on failure and returns a Resource on success. Note that the documentation of this function in client.js claims @return {Promise<Object>} FHIR resource