Health tool (FHIR/HL7)

The health tool generates Ballerina library packages and Ballerina templates for FHIR APIs for developing healthcare integrations.

These artifacts generated by the tool are primarily focused on the Fast Healthcare Interoperability Resources (FHIR) standard and are developed using Ballerina.

Info: It is supported from Ballerina Swan Lake version 2201.8.1 onwards.

Prerequisites

Download a directory containing all FHIR specification definition files. You can download a preferred standard implementation guide from the FHIR Implementation Guide registry.

Note: It is recommended to use a Standard for Trial Use (STU) or higher release level of the implementation guides. Make sure that the downloaded specification archive has the StructureDefinition, ValueSet, and CodeSystem files for the Implementation Guide (IG) resources when extracted.

Install the tool

Execute the command below to pull the Health tool from Ballerina Central.

Copy
$ bal tool pull health
health:2.0.0 pulled successfully.
health:2.0.0 successfully set as the active version.

Usage

The Ballerina Health tool has the following usages.

The general usage of the tool is as follows.

Note: Make sure to give the directory path of the downloaded FHIR definitions as the last argument.

Copy
$ bal health fhir [-m | --mode] <mode-type>
            [-o | --output] <output-location>
            [--package-name] <ballerina-package-name>
            [--dependent-package] <dependent-ballerina-package-name> 
            [--org-name] <package-or-template-organization-name>
            [--included-profile] <profile(s)-to-include-in-generation>
            [--excluded-profile] <profile(s)-to-exclude-in-generation>
            <fhir-specification-directory-path>

Command options

The parameters that are available with the tool are listed below.

Command optionDescriptionUsage
-m, --modeMode type can be package or template. The Ballerina package and API templates are generated according to the mode.
-o, --outputThe Ballerina artifacts are generated at the same location from which the bal health fhir command is executed. You can point to another directory location by using the (-o|--output) flag.
--package-nameName of the Ballerina package to be generated.
--dependent-packageBallerina package name, which contains the IG resources.
--org-nameOrganization name of the Ballerina package or API templates to be generated.
--included-profileGenerate one or more specific FHIR profiles as Ballerina templates for FHIR APIs.
--excluded-profileSkip one or more specific FHIR profiles when generating Ballerina templates for FHIR APIs.

FHIR package generation

The FHIR resources in the implementation guide will be represented as Ballerina records including the correct cardinality constraints and metadata. FHIR integration developers can leverage the generated package when transforming custom health data into FHIR format without referring to the specification.

Package generation usage

The tool supports the package generation usage as follows.

Copy
$ bal health fhir [-m | --mode] package
            [--package-name] <ballerina-package-name>
            [-o | --output] <output-location>
            [--org-name] <package-organization-name>
            <fhir-specification-directory-path>

Package generation command options

Command optionDescriptionMandatory/Optional
-m, --modeIf mode is set to package, a Ballerina package will be generated including all the records and types.Mandatory
--package-nameName of the Ballerina package to be generated. The package name can be explicitly set using this argument. Unless specified, the default name of the implementation guide will be taken to construct the name of the package. For more information, see the the name field.Mandatory
-o, --outputLocation of the generated Ballerina artifacts. If this path is not specified, the output will be written to the same directory from which the command is run.Optional
--org-nameOrganization name of the Ballerina package to be generated. For more information, see the org field.Optional

Package generation example

Follow the steps below to try out an example package generation use case of the Health tool.

Clone the example project

Clone the artifacts of the example and extract them to a preferred location.

The cloned directory includes the artifacts below that will be required to try out this example (Ballerina project and the FHIR specification files).

  • The ig-carinbb/definitions directory: includes the definition files of the FHIR specification.
  • The carinbb-patient-service directory: includes the Ballerina project containing the artifacts (i.e., the Ballerina.toml, Dependencies.toml, and service.bal files) to be executed.

Generate the package

Follow the steps below to run the Health tool and create the Ballerina package.

  1. Navigate to the cloned working-with-health-tool/package-generation directory.

  2. Run the tool with the required command options to generate the package.

    Note: This example uses the definitions files downloaded from the JSON Definitions ZIP archive of the Carin BB implementation guide to generate the package.

    Copy
    $ bal health fhir -m package -o ig-carinbb/gen --org-name healthcare_samples --package-name carinbb_package ig-carinbb/definitions/
    [INFO] Ballerina FHIR package generation completed successfully. Generated package can be found at: /tmp/healthcare-samples/working-with-health-tool/package-generation/ig-carinbb/gen
    

    The generated folder (i.e., working-with-health-tool/package-generation/ig-carinbb/gen) will contain the following directory structure.

    └── carinbb_package
        ├── Ballerina.toml
        ├── Package.md
        ├── initializer.bal
        ├── resource_c4bbcoverage.bal
        ├── resource_c4bbexplanation_of_benefit.bal
        ├── resource_c4bbexplanation_of_benefit_inpatient_institutional.bal
        ├── resource_c4bbexplanation_of_benefit_oral.bal
        ├── resource_c4bbexplanation_of_benefit_outpatient_institutional.bal
        ├── resource_c4bbexplanation_of_benefit_pharmacy.bal
        ├── resource_c4bbexplanation_of_benefit_professional_non_clinician.bal
        ├── resource_c4bborganization.bal
        ├── resource_c4bbpatient.bal
        ├── resource_c4bbpractitioner.bal
        ├── resource_c4bbrelated_person.bal
        ├── resources
        ├── tests
        └── variables.bal
    
  3. Build the generated package.

    Copy
    $ cd ig-carinbb/gen/carinbb_package
    $ bal pack
    Compiling source
            healthcare_samples/carinbb_package:0.0.1
    
    Creating bala
            target/bala/healthcare_samples-carinbb_package-any-0.0.1.bala
    
  4. Push it to a repository.

    Tip: You can push either to the local repository or to Ballerina Central, which is a remote repository.

    Copy
    $ bal push --repository local
    Successfully pushed target/bala/healthcare_samples-carinbb_package-any-0.0.1.bala to 'local' repository.
    

Use the generated package

Follow the steps below to use the generated package by running the cloned Ballerina project.

  1. Navigate to the cloned working-with-health-tool/package-generation/carinbb-patient-service directory.

    Info: You can change the dependency (name and version) of the generated package in the carinbb-patient-service/Ballerina.toml file of this cloned Ballerina project directory as preferred.

  2. Run the cloned Ballerina project and validate the output.

    Copy
    $ bal run
    Compiling source
            healthcare_samples/carinbb_ballerina:1.0.0
    
    Running executable
    
  3. Invoke the API to try it out.

    Copy
    $ curl http://localhost:9090/Patient/2121
    

    You can view the response shown below.

    Copy
    {
        "resourceType": "Patient",
        "gender": "male",
        "id": "2121",
        "identifier": [
            {
                "system": "http://hl7.org/fhir/sid/us-ssn",
                "value": "2121"
            }
        ],
        "meta": {
            "profile": [
                "http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient"
            ]
        },
        "name": [
            {
                "family": "Doe",
                "given": [
                    "John",
                    "Hemish"
                ]
            }
        ]
    }

FHIR template generation

The tool can also be used to generate Ballerina templates for FHIR APIs for the FHIR resources in an implementation guide. FHIR integration developers can utilize these API templates by customizing them to align with their specific business logic and subsequently exposing them as standard FHIR APIs.

Template generation usage

The tool supports the template generation usage as follows.

Copy
$ bal health fhir [-m | --mode] template
            [--dependent-package] <dependent-ballerina-package-name> 
            [-o | --output] <output-location>
            [--org-name] <template-organization-name>
            [--included-profile] <profile(s)-to-include-in-generation>
            [--excluded-profile] <profile(s)-to-exclude-in-generation>
            <fhir-specification-directory-path>

Template generation command options

Command optionDescriptionMandatory/Optional
-m, --modeIf mode is set to template, Ballerina templates for FHIR APIs can be generated.Mandatory
--dependent-packageFully qualified name of the published Ballerina package containing the IG resources (e.g., <org>/<package>). This option can be used to generate Ballerina templates for FHIR APIs specifically for the resources in the given IG. The package name part of this value will be added as a prefix to the template name.Mandatory
-o, --outputLocation of the generated Ballerina artifacts. If this path is not specified, the output will be written to the same directory from which the command is run.Optional
--org-nameOrganization name of the Ballerina templates for FHIR APIs to be generated. For more information, see the org field.Optional
--included-profileIf one or more specific FHIR profiles need to be generated as Ballerina templates, specify the profile URL(s) as the value of this parameter. This argument can be used more than once.Optional
--excluded-profileIf one or more specific FHIR profiles need to be skipped when generating Ballerina templates, specify the profile URL(s) as the value of this parameter. This argument can be used more than once.Optional

Template generation example

Follow the steps below to try out an example template generation use case of the Health tool.

Clone the example project

Clone the artifacts of the example and extract them to a preferred location.

The cloned directory includes the ig-uscore/definitions directory, which includes the definition files of the FHIR specification.

Generate the templates

Follow the steps below to run the Health tool and generate the Ballerina templates for FHIR APIs for the selected package.

Note: You need to have a Ballerina package containing IG-specific FHIR resource data models to generate FHIR IG templates. You can use the package mode of the Health tool for easy generation of this package. This example uses the health.fhir.r4.uscore501 package in Ballerina Central.

  1. Navigate to the cloned working-with-health-tool/template-generation directory.

  2. Run the tool with the required command options to generate the Ballerina templates for FHIR APIs.

    Note: This example uses the definitions files downloaded from the JSON Definitions ZIP archive of the US Core implementation guide to generate the templates.

    Copy
    $ bal health fhir -m template -o ig-uscore/gen --org-name healthcare_samples --dependent-package ballerinax/health.fhir.r4.uscore501 ig-uscore/definitions
    [INFO] Generating templates for all FHIR profiles...
    [INFO] Ballerina FHIR API templates generation completed successfully. Generated templates can be found at: /tmp/healthcare-samples/working-with-health-tool/template-generation/ig-uscore/gen
    

    The generated folder (i.e., working-with-health-tool/template-generation/ig-uscore/gen) will contain the following directory structure.

    .
    |____device
    | 	|____api_config.bal
    | 	|____service.bal
    |	|____.gitignore
    |	|____Package.md
    | 	|____Ballerina.toml
    |____observation
    |	|____api_config.bal
    | 	|____service.bal
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml
    |____patient
    | 	|____api_config.bal
    | 	|____service.bal
    | 	|____Dependencies.toml
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml
    |____practitioner
    | 	|____api_config.bal
    | 	|____service.bal
    | 	|____Dependencies.toml
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml
    |____practitionerrole
    |	|____api_config.bal
    |	|____service.bal
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml
    |____procedure
    | 	|____api_config.bal
    | 	|____service.bal
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml
    |____relatedperson
    | 	|____api_config.bal
    | 	|____service.bal
    | 	|____.gitignore
    | 	|____Package.md
    | 	|____Ballerina.toml    
    

Use the generated templates

Follow the steps below to use the generated API templates by running the cloned Ballerina project.

  1. Navigate to the generated working-with-health-tool/template-generation/ig-uscore/gen/practitioner/ directory.

  2. Update the get fhir/r4/Practitioner/[string id] method in the corresponding working-with-health-tool/template-generation/ig-uscore/gen/practitioner/service.bal file with the code below to implement the business logic.

    Info: You can use VS Code to open the generated Ballerina templates for FHIR APIs and implement the business logic in it. It has Ballerina language support via an extension, which assists on both syntactic and semantic aspects.

    Copy
    isolated resource function get fhir/r4/Practitioner/[string id] (r4:FHIRContext fhirContext) returns Practitioner|r4:OperationOutcome|r4:FHIRError {
        Practitioner practitioner = {
            resourceType: "Practitioner",
            id: "1",
            meta: {
                lastUpdated: "2021-08-24T10:10:10Z",
                profile: [
                    "http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner"
                ]
            },
            identifier: [
                {
                    use: "official",
                    system: "http://hl7.org/fhir/sid/us-npi",
                    value: "1234567890"
                }
            ],
            name: [
                {
                    use: "official",
                    family: "Smith",
                    given: [
                        "John",
                        "Jacob"
                    ],
                    prefix: [
                        "Dr."
                    ]
                }
            ]
        };
        return practitioner;
    }
  3. Run the service and verify the output response.

    Copy
    $ bal run
    Compiling source
            healthcare_samples/health.fhir.r4.uscore501.practitioner:1.0.0
    
    Running executable
    
  4. Invoke the API to try it out.

    Copy
    $ curl http://localhost:9090/fhir/r4/Practitioner/1
    

    You can view the response shown below.

    Copy
    {
    "resourceType":"Practitioner",
    "identifier":[
        {
            "system":"http://hl7.org/fhir/sid/us-npi",
            "use":"official",
            "value":"1234567890"
        }
    ],
    "meta":{
        "lastUpdated":"2021-08-24T10:10:10Z",
        "profile":[
            "http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner"
        ]
    },
    "name":[
        {
            "given":[
                "John",
                "Jacob"
            ],
            "prefix":[
                "Dr."
            ],
            "use":"official",
            "family":"Smith"
        }
    ],
    "id":"1"

CDS template generation

A Ballerina service template can be generated from CDS hook definitions. This template will also include basic functionalities such as validation, prefetch, etc., and it will facilitate the developers' implementation of the required connection with the external decision support system to run the CDS server. The generated Ballerina service project will be written into the provided output location.

Supported CDS version: 2.0

Template generation usage

Copy
$ bal health cds
            [--org-name] <template-organization-name>
            [--package-name] <name-of-the-package>
            [--package-version] <version-of-the-package>
            [-o | --output] <output-location>
            [-i | --input] <cds-hook-definitions-file-path>

CDS template generation command options

Command optionDescriptionMandatory/Optional
-i, --inputThe input file with CDS hook definitions which will be used to generate the Ballerina service. Only TOML files are accepted.Mandatory
--org-nameThe organization name to be used for the generated Ballerina template. For more information, see the org field.Optional
--package-nameThe package name to be used for the generated Ballerina template. If not specified, health.fhir.templates.crd will be used to construct the name of the package.Optional
--package-versionThe version to be used for the generated Ballerina template.Optional
-o, --outputThe location of the generated Ballerina artifacts. If this path is not specified, the output will be written to the same directory from which the command is run.Optional

Template generation example

Follow the steps below to try out a sample CDS template generation use case of the Health tool.

Create the CDS definition file

Create a TOML file with the CDS hook definitions. Refer to CDS specifications for more information about the attributes.

Sample cds-definitions.toml file:

[[cds_services]]
id = "static-patient-greeter"
hook = "patient-view"
title = "Static CDS Service Example"
description = "An example of a CDS Service that returns a static set of cards"
usageRequirements = "Note: functionality of this CDS Service is degraded without access to a FHIR Restful API as part of CDS recommendation generation."
[cds_services.prefetch]
patientToGreet = "Patient/{{context.patientId}}"

[[cds_services]]
id = "book-imaging-center"
hook = "order-dispatch"
title = "Book an imaging center"
description = "This hook can be used when booking imaging center"

Generate the templates

Follow the steps below to run the Health tool and generate the Ballerina templates for CDS for the given hook definitions.

  1. Navigate to the working directory that contains the CDS hook definitions file.

  2. Run the tool with the required command options to generate the Ballerina template.

Copy
$ bal health cds --org-name wso2 --package-name cds_service  --package-version 1.0.0 -i cds-definitions.toml
[INFO] Ballerina CDS service template generation completed successfully. The generated project can be found at /Users/tom/Desktop/working_directory/generated-template/cds_service

The generated folder (i.e., working_directory/template-generation/cds_service) will contain the following directory structure.

.
├── Ballerina.toml
├── Config.toml
├── Package.md
├── decision_engine_connector.bal
├── interceptor.bal
├── service.bal
└── utils.bal

Use the generated templates

Follow the steps below to use the generated CDS service template.

  1. Navigate to the generated working_directory/template-generation/cds_service/ directory.

  2. Complete the decision system connectivity implementation. The decision_engine_connector file contains placeholder functions that must be implemented to connect with external decision systems. Please follow the instructions in the file.

Info: You can use VS Code to open the generated Ballerina templates for FHIR APIs and implement the business logic in it. It has Ballerina language support via an extension, which assists on both syntactic and semantic aspects.

Sample implementation for a placeholder function:

isolated function connectDecisionSystemForBookImagingCenter(cds:CdsRequest cdsRequest, string hookId) returns cds:CdsResponse|cds:CdsError {
    cds:Card card1 = {
        summary: "Prior authorization",
        indicator: "critical",
        'source: {
            label: "Static CDS Service Example",
            url: "https://example.com",
            icon: "https://example.com/img/icon-100px.png"
        },
        detail: "Obtain prior authorization to avoid claim denials and patient financial liability. Contact: For questions, reach out to the insurance provider or billing department.",
        suggestions: [{label: "Kindly get pri-authorization"}],
        selectionBehavior: "at-most-one",
        links: [{label: "Prior-auth", url: "https://www.acmehealth.com/policies/lab-coverage", 'type: cds:ABSOLUTE}]
    };

    cds:Card card2 = {
        summary: "Alternative centers",
        indicator: "info",
        'source: {
            label: "Static CDS Service Example",
            url: "https://example.com",
            icon: "https://example.com/img/icon-100px.png"
        },
        detail: "Discuss alternative imaging centers with patients to enhance access and affordability. For assistance, reach out to the facility's scheduling department or insurance provider.",
        suggestions: [
            {label: "The selected imaging center is far away from your location. Please select nearby one. Suggested: Asiri labs : Col - 3"}
        ],
        selectionBehavior: "any"
    };

    cds:CdsResponse cdsResponse = {
        cards: [card1, card2],
        systemActions: []
    };
    return cdsResponse;
}
  1. Run the service.

    Copy
    $ bal run
    Compiling source
            healthcare_samples/health.fhir.r4.uscore501.practitioner:1.0.0
    
    Running executable
    
  2. Invoke the API to try it out.

    curl --location 'http://localhost:8080/cds-services/book-imaging-center' \
    --header 'Content-Type: application/json' \
    --data '{
     "hookInstance": "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
     "hook": "order-dispatch",
     "context": {
         "patientId": "12345",
         "dispatchedOrders": [
             "ServiceRequest/proc002"
         ],
         "performer": "Organization/O12345",
         "fulfillmentTasks": [
             {
                 "resourceType": "Task",
                 "status": "draft",
                 "intent": "order",
                 "code": {
                     "coding": [
                         {
                             "system": "http://hl7.org/fhir/CodeSystem/task-code",
                             "code": "fulfill"
                         }
                     ]
                 },
                 "focus": {
                     "reference": "ServiceRequest/proc002"
                 },
                 "for": {
                     "reference": "Patient/12345"
                 },
                 "authoredOn": "2016-03-10T22:39:32-04:00",
                 "lastModified": "2016-03-10T22:39:32-04:00",
                 "requester": {
                     "reference": "Practitioner/wdwdwd"
                 },
                 "owner": {
                     "reference": "Organization/some-performer"
                 }
             }
         ]
     }
    }'
    

    You can view the response shown below.

    Copy
    {
      "resourceType": "Practitioner",
      "identifier": [
        {
          "system": "http://hl7.org/fhir/sid/us-npi",
          "use": "official",
          "value": "1234567890"
        }
      ],
      "meta": {
        "lastUpdated": "2021-08-24T10:10:10Z",
        "profile": [
          "http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner"
        ]
      },
      "name": [
        {
          "given": ["John", "Jacob"],
          "prefix": ["Dr."],
          "use": "official",
          "family": "Smith"
        }
      ],
      "id": "1"
    }