We wanted to enhance our FHIR Blaze app with ML assisted image review. FHIR Blaze is a scenario-specific app that can be used with any FHIR-capable system. Rather than implement an image viewer in the FHIR Blaze app we wanted to use an existing image viewer library. We decided to package the viewer into an existing SMART (Substitutable Medical Apps and Reusable Technology) so that we could reuse much of the functionality that was already written. Inside FHIR Blaze we will include an HTML link on each Patient's page that has all the information needed to launch our SMART App.
This post will show the simple steps we used to launch the custom SMART app from our scenario-specific app.
In this post I won't explain how to authorize a SMART app from your FHIR interface. Instructions for how to authorize a SMART app are found here.
Architecture
FHIR Blaze is a scenario-specific FHIR compatible app. It's written in Blazor/Web Assembly and hosted in an Azure Static Web App.
Chestist is our SMART app. It's written in React and based on the patient-viewer sample SMART app. It is hosted as an Azure Static Web App.
FHIR API: We used the Azure API for FHIR as our FHIR provider. Some customers use thier EMR as the FHIR provider.
Identity Provider: We used the Azure AD Smart on FHIR Proxy. The Proxy integrates FHIR authentication requests between the FHIR API for Azure and Azure Active Directory.
SMART Authentication Flow
SMART HealthCare has detailed documentation about authentication here: SMART App Authorization Guide (smarthealthit.org)
Let’s summarize:
1. FHIR Blaze will display a link on each patient’s page that will launch the SMART app in a new browser window. The link will contain the context of the patient and information for acquiring authentication to the bakend FHIR repository.
2. The SMART app will then obtain a token from the identity provider, as the signed in user, to access the patient’s data.
Creating the Link
This seems easy! We just need a link with the right info in it.
Our goal is a link that contains:
The URL of the SMART app, the Patient ID, and the FHIR Repository authentication information.
In reality this is what our link will look like:
https://<SMART App URL>/?launch= <Encoded Patient ID> &iss=<FHIR Proxy URL>
for example:
Let’s get started!
We need to set our constants.
First the SMART app URL.
string _launcherURL=” https://zeckcg7jlal6q-chestist-app.azurewebsites.net”;
Second the FHIR API identity authority. You can get this by navigating to your Azure API for FHIR in the Azure portal, > Authentication > Audience
string _launcherURL=” https://zeckcg7jlal6q-chestist-app.azurewebsites.net”;
string_authority = “https://chestist-fhir-api.azurehealthcareapis.com”;
Next let’s assemble the patient information.
string _launcherURL=” https://zeckcg7jlal6q-chestist-app.azurewebsites.net”;
string_authority = “https://chestist-fhir-api.azurehealthcareapis.com”;
var ctx = new
{
patient = CurrentPatient.Id
};
Next let’s encode the JSON version of the context:
string _launcherURL=” https://zeckcg7jlal6q-chestist-app.azurewebsites.net”;
string_authority = “https://chestist-fhir-api.azurehealthcareapis.com”;
var ctx = new
{
patient = CurrentPatient.Id
};
var jsonctx=JsonConvert.SerializeObject(ctx);
var bytes = Encoding.UTF8.GetBytes(jsonctx);
string payloadJson= HttpUtility.UrlEncode(Convert.ToBase64String(bytes));
var jsonEncoded = EncodePayload(payloadJson);
Finally let’s put it all together
string _launcherURL=” https://zeckcg7jlal6q-chestist-app.azurewebsites.net”;
string_authority = “https://chestist-fhir-api.azurehealthcareapis.com”;
var ctx = new
{
patient = CurrentPatient.Id
};
var jsonctx=JsonConvert.SerializeObject(ctx);
var bytes = Encoding.UTF8.GetBytes(jsonctx);
string payloadJson= HttpUtility.UrlEncode(Convert.ToBase64String(bytes));
var jsonEncoded = EncodePayload(payloadJson);
var result = new StringBuilder();
result.Append(_launchUrl);
result.Append($"?launch={jsonEncoded}");
result.Append($"&iss={_authority}");
string url= result.ToString();
That’s it! Now wherever we put this link we will be able to launch our app.
See the sample code in our FHIR Blaze App:
Reference Component that renders links: FhirBlaze/ChestistLauncher.razor at main · microsoft/FhirBlaze (github.com)
Reference Class that assembles links: FhirBlaze/SmartLauncher.cs at main · microsoft/FhirBlaze (github.com)
What’s next?
So now that you can use the library of preexsisting SMART apps from your scenario specific app- the sky is the limit. For example you could:
- Want to develop / test / run a SMART app by a potential user? Just create s small scenario-specific (or clone our FHIR Blaze App) and launch your SMART app from there
- Want to create a super-slimmed down app that gives very limited access to an EMR, but still want those rich interfaces? Just throw a SMART app on your slimmed down FHIR app.
- Want to package functionality? Why not do it in a SMART app and include the above instructions for users of your app
We can't wait to see what you'll develop!