FHIR Shorthand
0.12.0 - CI Build

FHIR Shorthand, published by HL7 International - FHIR Infrastructure Group. This is not an authorized publication; it is the continuous build for version 0.12.0). This version is based on the current content of https://github.com/HL7/fhir-shorthand/ and changes regularly. See the Directory of published versions


FHIR Shorthand (FSH) is a specially-designed language for defining the content of FHIR Implementation Guides (IGs). It is simple and compact, with tools to produce Fast Healthcare Interoperability Resources (FHIR) profiles, extensions and IGs. FSH is compiled from text files to FHIR artifacts using SUSHI. To get started using FSH, you need to install and run SUSHI using the steps below.

Platform notes:

Symbol Explanation
💻 Indicates information or command specific to Windows. A command window can be launched by typing cmd at the Search Windows tool.
🍎 Indicates information or command specific to OS X. Commands can be run within the Terminal application.
$ Represents command prompt (may vary depending on platform)

Step 1: Install Node.js

SUSHI requires Node.js. To install Node.js, go to https://nodejs.org/ and you should see links to download an installer for your operating system. Download the installer for the LTS version. If you do not see a download appropriate for your operating system, click the “other downloads” link and look there. Once the installer is downloaded, run the installer. It is fine to select default options during installation.

Ensure that Node.js is correctly installed by opening a command window and typing the following two commands. Each command should return a version number.

$ node --version
$ npm --version

Step 2: Install SUSHI

To install SUSHI, return to the command prompt, and issue this command:

$ npm install -g fsh-sushi

Check the installation by typing the following command:

$ sushi -h

If the command outputs instructions on using SUSHI command line interface (CLI), you’re ready to run SUSHI.

Step 3: Download Sample FSH Tank

To start with some working examples of FSH files and a skeleton FSH tank, download the fsh-tutorial-master.zip file and unzip it into a directory of your choice. The zip file is also available from the Downloads menus, directly above.

After the file is unzipped, you should see two subdirectories:

  • FishExample
  • FishExampleComplete

Change the working directory to FishExample. There are two FSH files:

  • FishPatient.fsh
  • Veterinarian.fsh

In addition, there is a package.json file and a subdirectory, /ig-data, containing some inputs for building the IG.

Step 4: Run SUSHI

Now that you have SUSHI installed and a minimal FSH tank, open up a command window, and navigate to the FishExample directory. Run SUSHI on those FSH files by executing:

$ sushi .

Note: The dot (.) represents “this directory,” the location of the FSH files. You can also specify the location explicitly by replacing the dot with a directory path.

Running SUSHI will create a FishExample/build/input/resources directory, and populate it with the files needed to create the IG using the HL7 FHIR IG Publisher tool.

While running SUSHI, there will be a series of informational message. When SUSHI completes, you should see a summary output similar this:

  Profiles:    2
  Extensions:  0
  Instances:   0
  ValueSets:   0
  CodeSystems: 0
  Errors:      0
  Warnings:    0

The files generated by SUSHI are located in the FishExample/build directory. Check that the build/input/profiles subdirectory contains two generated structure definitions.

Step 5: Generate the Sample IG

Now change working directory of the command window to the build directory. At the command prompt, enter:

💻 $ _updatePublisher

🍎 $ ./_updatePublisher.sh

This will download the latest version of the HL7 FHIR IG Publisher tool into ./build/input-cache. This step can be skipped if you already have run the command recently, and have the latest version of the IG Publisher tool.

Note: If you have never run the IG Publisher, you may need to install Jekyll first. See Installing the IG Publisher for details.

Note: If you are blocked by a firewall, or if for any reason _updatePublisher fails to execute, download the current IG Publisher jar file here. When the file has downloaded, move it into the directory /FishExample/build/input-cache (create the directory if necessary.)

Now run:

💻 $ _genonce

🍎 $ ./_genonce.sh

This will run the HL7 FHIR IG generator, which may take several minutes to complete.

After the publisher is finished, open the file /FishExample/build/output/index.html to see the resulting IG.

If you click on the Artifacts Summary item in the menu, you will see that the IG contains two profiles, FishPatient and Veterinarian. If you look at each of them, you will notice that they have minimal differentials. The only way in which they differ from their base resource is that they require at least one name.

Step 6: Setting Cardinalities in a Profile

It is not widely known, but FHIR is designed to be used for veterinary medicine as well as human. For a non-human patient, we need to record the species. The Patients in this Tutorial are going to be various species of fish 🐟.

Since fish don’t get legally married (although some species do pair bond) and they don’t communicate in a human language, the first thing we’ll do in the FishPatient profile is eliminate these elements. To do this, open the file FishPatient.fsh in your favorite plain-text editor, and add the following rules after the last non-blank line in the file:

* maritalStatus 0..0
* communication 0..0

Note that rules start with *. FSH expresses cardinality as, {min}..{max}, the same as FHIR.

Step 7: Create a Species Extension for FishPatient

To specify the species of our aquatic patients, we’ll need an extension.

We have a choice of whether to make the extension inline or standalone. Inline extensions do not result in a separate StructureDefinition, and cannot be reused in other profiles. Standalone extensions are the opposite: they have independent StructureDefinitions, and can be reused. For this example, let’s make a standalone extension.

Extensions are created using the contains keyword. To add a standalone species extension, add the following rule after the cardinality rules:

* extension contains FishSpecies named species 0..1

Note: You must be running SUSHI version 0.10.0 or higher for this to not generate a parsing error

This rule states that the extension array of the Patient resource will incorporate the FishSpecies extension with the local name species.

To define the FishSpecies extension, add the following lines to the end of the FishPatient.fsh file:

Extension:   FishSpecies
Id:          fish-species
Title:       "Fish Species"
Description: "The species of the fish."

NOTE: FSH ignores extra whitespace, so authors can choose to use whitespace for improved visual alignment, as in the extension definition above.

Run SUSHI again ($ sushi .). The count of Extensions should now be 1.

Step 8: Define a Value Set for Fish Species

The FishSpecies extension doesn’t quite do its job yet, because we haven’t specified what type of values it might accept. To add this information, enter these lines following the description of FishSpecies:

* value[x] only CodeableConcept
* valueCodeableConcept from FishSpeciesValueSet (extensible)

The first rule restricts the value[x] (a built-in element of every FHIR extension) to a CodeableConcept using the only keyword. The second binds it to a value set (yet to be defined) using the from keyword. The binding strength will be extensible.

To define FishSpeciesValueSet, add the following lines to the same file:

ValueSet:    FishSpeciesValueSet
Title:       "Fish Species Value Set"
Id:          fish-species-value-set
Description: "Codes describing various species of fish, taken from SNOMED-CT."
* codes from system http://snomed.info/sct where concept is-a SCT#90580008  "Fish (organism)"

The rule in the value set definition selects all codes from SNOMED-CT that are children of the concept “Fish (organism)”.

Run SUSHI again. The count of ValueSets should now be 1. Try generating the IG by changing directories to build and running _genonce again. Open the file /FishExample/build/output/index.html to see the resulting IG.

  • Do you see where the FishPatient profile is in the IG?
  • Does the differential reflect your changes?
  • How does FHIR render the value set you defined?

Step 9: Define an Alias

An Alias is a way to define a shorthand for a URL or OID. For example, in the extension definition above, we could have defined an Alias to make referencing the http://snomed.info/sct URL easier, as shown below. Aliases are conventionally defined at the top of the file.

Add this line at the top of the FishPatient.fsh file:

Alias: SCT = http://snomed.info/sct

and then replace the last line with:

* codes from system SCT where concept is-a #90580008 "Fish (organism)"

Using aliases has no effect on the IG; it simply makes the FSH code a bit neater.

Step 10: Create Shorty, an Instance of FishPatient

Every IG should provide examples of its profiles. We should provide an example instance of FishPatient. Our patient example is Shorty. Create this example instance using the Instance keyword, with InstanceOf set to FishPatient and Usage set to Example.

Include the following information about Shorty in the instance:

  • His given (first) name is “Shorty” and his family (last) name is “Koi-Fish”.
  • Shorty is a Koi fish (Cyprinus rubrofuscus), represented as SNOMED-CT code 47978005 “Carpiodes cyprinus (organism)”.

If you need help with this, you can reference the Defining Instances section of the specification. If you still need help, you can peek at the FSH files in the FishExampleComplete directory.

Run SUSHI again, and re-generate the IG.

  • Did it compile without errors?
  • What does the IG look like now?

Step 11: Create a Veterinarian Profile

Now, add constraints and/or extensions to the Veterinarian profile:

  • Add qualifications consistent with a Veterinary practice. Qualifications are taken from code system http://hl7.org/fhir/sid/ca-hc-npn, and the code is 174MM1900N “Other Service Providers; Veterinarian; Medical Research”.

  • In addition, slice the identifier array, making a license number required. The code system is http://terminology.hl7.org/CodeSystem/v2-0203 and the code is LN, for “License number”.

If you need help with this, you can reference the Fixed Value Rules and Slicing Rules sections of the specification. If you still need help, you can peek at the FSH files in the FishExampleComplete directory.

Run SUSHI again, and re-generate the IG.

  • Did it compile without errors?
  • What does the IG look like now?

Congratulations! You’ve completed the FSH tutorial. It might be time to feast on some sushi!