Building Next-Gen FHIR Apps
A Step-By-Step Guide
Jun 15, 2020

Today’s tutorial is courtesy of Asymmetrik Software Developer Shane O’Neill. If you missed Shane’s recent webinar on building next-generation FHIR apps, you can watch it here, or use the step-by-step guide below.

Building Next-Gen FHIR Apps

Historically, a lot of example FHIR applications online are limited in terms of scalability and maintainability. Typically, they tend to have the bare minimum of features and do not provide the developer a lot of help. We can do much better. Using the Asymmetrik FHIR App Starter, we can cut right through the boilerplate setup and get straight to coding the logic of our application.

Let’s start by cloning Asymmetrik’s FHIR App Starter and opening up VS Code:

$ git clone
$ code fhir-app-starter

Your VS Code might look a little different than mine due to different plugins and theming. That’s ok! Next, we’ll address how this project works.

Project Structure

Let’s go over the roles of some of these directories.

Src
The project structure of our React app is modular and leverages the Container Components pattern for easy organization for interacting with the Redux store.

Our containers hold everything they need to render themselves, connect to the Redux store, run Redux Sagas. Let’s go over each part:

  • Actions.js These hold our action creators
  • Constants.js This where our action types are kept
  • Index.js This is our React component
  • Reducers.js Our reducers move dispatched actions from our Sagas into our state
  • Sagas.js These hold our sagas which handle async actions and flow control
  • Selectors State selectors using Reselect

Config

This directory holds our Webpack configuration and also our SMART configuration. SMART (aka SMART on FHIR), is a protocol for launching FHIR Apps securely against FHIR Servers. Read more about SMART here.

Public

Public holds our static file templates for creating a launch.html and index.html. These two routes are essential for completing the SMART on FHIR handshake.

Running and Building our App

If you want to run the application using a Webpack Dev Server, simply run yarn start. This will host the application on port 3000.

We see an “Unconnected to a FHIR Server” banner because we did not launch from an EHR. Let’s do that using Cerner’s Code Sandbox.

  • Step 1: Create an account on Cerner’s Code Sandbox and log in
  • Step 2: Create an application by clicking “New App”

    If you are developing locally, use the following:

    Config Example Value
    App Name Anything you want
    SMART Launch URI http://localhost:3000/launch.html
    Redirect URI http://localhost:3000/
    App Type Provider
    FHIR Spec DSTU2
    Authorized Yes
    Patient Scopes Patient.read Observation.read Condition.read
    User Scopes Not needed unless your requirements need this
  • Step 3: Update your app config
  • The app builds the information into the application automatically. All you need to do is update the config/smart.js file.

    After updating your config, restart your application.
    $ yarn start

  • Step 4: Launch from Cerner’s Code Sandbox

    On Cerner’s Code Sandbox, click into your application. Select Begin Testing. Select a Patient, and Select Launch. After launching you may be redirected to a login page. Use username portal and password portal. If you configured things correctly, you should see your application has been launched properly.

Let’s Build a New Feature Together

In our home component, let’s request a Patient’s conditions using Redux Saga.

These changes to our sagas will make it so a Patient’s conditions are dispatched. We are dispatching an action with the type of Home/LOAD_CONDITIONS and we are giving it our conditions in the form of a payload property. This way we can capture this action in our reducers and handle it appropriately. Now, let’s update our reducers.

There are already a few cases that are catching other actions here, but we can add our new action and catch it too. We can update our draft state, which will become the next state, with our conditions. So now they are going to be located within our state. We can map this state change to our Home component’s props, and then render them on the screen. Our component is located in index.js, so let’s make our code changes there. First we need to map our Redux state to our props by modifying the mapStateToProps function.

Now we have conditions in our Component’s props, and we can render it however we like. For this example, I just made a small table using Semantic UI.

We can see our changes by relaunching our application.

We can see the Conditions of our Patient are displayed.

Wrapping Up

Today we successfully cloned fhir-app-starter, registered a new app on Cerner’s Code Sandbox, and even built a new feature. Give it a try and let us know how you did by tweeting Asymmetrik or myself! And, feel free to raise questions or issues on our Github.

Shane O’Neill is a Software Developer at Asymmetrik specializing in building FHIR Apps, FHIR Servers, and the processing of FHIR resources. He has helped develop the popular MongoDB FHIR Server implementation node-fhir-server-mongo. Some of his favorite technologies to work with are NodeJS, ReactJS, Redux, and PostgreSQL. You can catch him next at FHIR DevDays, where he’ll be presenting on June 18th.