Thursday, September 23, 2021

Launching a SMART App Demystified

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 

smart on fhir-SMART Azure.png

 

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.  

 

SameerDoshi_0-1632423107061.png

 

 

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:

https://zeckcg7jlal6q-chestist-app.azurewebsites.net/?launch=eyJwYXRpZW50IjoiNWViN2NhZDUtODEzYy00NzgyLWJiN2QtM2NmY2YwMzQ1ZTFmIn0%3d&iss=https://chestist-fhir-api.azurehealthcareapis.com

 

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();

 

 

SameerDoshi_1-1632424337978.png     SameerDoshi_2-1632424351533.png

 

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!

 

 

Posted at https://sl.advdat.com/3EJXxSR