Skip to content

FHIR Connector Example

Fast Healthcare Interoperability Resources (FHIR) is an interoperability standard for electronic exchange of healthcare information. The WSO2 EI FHIR connector can be used to invoke FHIR operations within WSO2 EI mediation logic.

In this example the connector uses the FHIR REST API to interact with FHIR. This connector uses the HAPI FHIR APIs to connect with a Test Server, which is an open source server licensed under the Apache Software License 2.0 (Java-based implementation of the FHIR specification).

What you'll build

Given below is a sample API that illustrates how you can connect to a FHIR server and invoke operations. It exposes FHIR functionalities as a restful service. Users can invoke the API with HTTP/HTTPs with required information.

  1. /create : creates a new patient at FHIR server
  2. /read : retrieve information about the patient from FHIR server
  3. /readSpecificResourceById: map this to the scenario is it read patient by Id
  4. /update : update patient information from FHIR server.
  5. /delete : remove added patient information from FHIR server.

To know the further information about these operations please refer this link.

Note: If no ID element is provided, or the value is wrong, the server responds with a HTTP 400 error code and provides an operation outcome identifying the issue.

The following diagram illustrates all the required functionality of the FHIR API service that you are going to build.

In here FHIR clients can invoke the API with HTTP/HTTPs with required information. The FHIR connector exposes each request to converting to the Health Level Seven International standards and then send to the resources available in the FHIR server.

This server is regularly loaded with a standard set of test data sets and also this server can store any data that related to administrative concepts such as patients, providers, organizations and devices, as well as a variety of clinical concepts including problems, medications, diagnostics, care plans and financial issues, among others.

FHIR Connector

Configure the connector in WSO2 Integration Studio

Follow these steps to set up the ESB Solution Project and the Connector Exporter Project.

  1. Open WSO2 Integration Studio and create an Integration Project. Creating a new Integration Project

  2. Right click on the project that you created and click on Add or Remove Connector -> Add Connector. You will get directed to the WSO2 Connector Store.

  3. Search for the specific connector and download it to the workspace. In this case, Salesforce is used as an example, but you can do this for the connector you require for your integration scenario.
    Search Connector in the Connector Store

  4. Click Finish, and your Integration Project is ready. The downloaded connector is displayed on the left side palette with its operations.

  5. You can drag and drop the operations to the design canvas and build your integration logic. Drag connector operations

  6. Right click on the created ESB Solution Project and select New -> Rest API to create the REST API.

  7. Specify the API name as SendisoTestAPI and API context as /resources. You can go to the source view of the XML configuration file of the API and copy the following configuration (source view).

<?xml version="1.0" encoding="UTF-8"?>
<api context="/resources" name="SampleApi" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST" url-mapping="/create">
        <inSequence>
            <property expression="json-eval($.base)" name="base" scope="default" type="STRING"/>
            <property expression="json-eval($.resourceType)" name="type" scope="default" type="STRING"/>
            <property expression="json-eval($.format)" name="format" scope="default" type="STRING"/>
            <log level="custom">
                <property expression="get-property('transport','Content-Type')" name="base"/>
            </log>
            <fhir.init>
                <base>http://hapi.fhir.org/baseR4</base>
            </fhir.init>
            <switch source="get-property('transport','Content-Type')">
                <case regex="application/json">
                    <property name="format" scope="default" type="STRING" value="json"/>
                    <fhir.create>
                        <type>{$ctx:type}</type>
                        <format>{$ctx:format}</format>
                    </fhir.create>
                </case>
                <case regex="application/xml">
                    <property name="format" scope="default" type="STRING" value="xml"/>
                    <fhir.create>
                        <type>{$ctx:type}</type>
                        <format>{$ctx:format}</format>
                    </fhir.create>
                </case>
                <default/>
            </switch>
            <log level="full" separator=","/>
            <send/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
    <resource methods="POST" url-mapping="/read">
        <inSequence>
            <property expression="json-eval($.base)" name="base" scope="default" type="STRING"/>
            <property expression="json-eval($.resourceType)" name="type" scope="default" type="STRING"/>
            <property expression="json-eval($.format)" name="format" scope="default" type="STRING"/>
            <fhir.init>
                <base>http://hapi.fhir.org/baseR4</base>
            </fhir.init>
            <switch source="get-property('transport','Content-Type')">
                <case regex="application/json">
                    <property name="format" scope="default" type="STRING" value="json"/>
                    <fhir.readResource>
                        <type>{$ctx:type}</type>
                        <format>{$ctx:format}</format>
                    </fhir.readResource>
                </case>
                <case regex="application/xml">
                    <property name="format" scope="default" type="STRING" value="xml"/>
                    <fhir.readResource>
                        <type>{$ctx:type}</type>
                        <format>{$ctx:format}</format>
                    </fhir.readResource>
                </case>
                <default/>
            </switch>
            <log level="full" separator=","/>
            <send/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
    <resource methods="POST" url-mapping="/readSpecificResourceById">
        <inSequence>
            <property expression="json-eval($.base)" name="base" scope="default" type="STRING"/>
            <property expression="json-eval($.resourceType)" name="type" scope="default" type="STRING"/>
            <property expression="json-eval($.format)" name="format" scope="default" type="STRING"/>
            <property expression="json-eval($.id)" name="id" scope="default" type="STRING"/>
            <property expression="json-eval($.summary)" name="summary" scope="default" type="STRING"/>
            <fhir.init>
                <base>http://hapi.fhir.org/baseR4</base>
            </fhir.init>
            <switch source="get-property('transport','Content-Type')">
                <case regex="application/json">
                    <property name="format" scope="default" type="STRING" value="json"/>
                    <fhir.readSpecificResourceById>
                        <type>{$ctx:type}</type>
                        <id>{$ctx:id}</id>
                        <format>{$ctx:format}</format>
                        <summary>{$ctx:summary}</summary>
                    </fhir.readSpecificResourceById>
                </case>
                <case regex="application/xml">
                    <property name="format" scope="default" type="STRING" value="xml"/>
                    <fhir.readSpecificResourceById>
                        <type>{$ctx:type}</type>
                        <id>{$ctx:id}</id>
                        <format>{$ctx:format}</format>
                        <summary>{$ctx:summary}</summary>
                    </fhir.readSpecificResourceById>
                </case>
                <default/>
            </switch>
            <log level="full" separator=","/>
            <send/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
    <resource methods="POST" url-mapping="/update">
        <inSequence>
            <property expression="json-eval($.base)" name="base" scope="default" type="STRING"/>
            <property expression="json-eval($.resourceType)" name="type" scope="default" type="STRING"/>
            <property expression="json-eval($.format)" name="format" scope="default" type="STRING"/>
            <property expression="json-eval($.idToUpdate)" name="idToDelete" scope="default" type="STRING"/>
            <fhir.init>
                <base>http://hapi.fhir.org/baseR4</base>
            </fhir.init>
            <switch source="get-property('transport','Content-Type')">
                <case regex="application/json">
                    <property name="format" scope="default" type="STRING" value="json"/>
                    <fhir.update>
                        <type>{$ctx:type}</type>
                        <idToUpdate>{$ctx:idToUpdate}</idToUpdate>
                        <format>{$ctx:format}</format>
                    </fhir.update>
                </case>
                <case regex="application/xml">
                    <property name="format" scope="default" type="STRING" value="xml"/>
                    <fhir.update>
                        <type>{$ctx:type}</type>
                        <idToUpdate>{$ctx:idToUpdate}</idToUpdate>
                        <format>{$ctx:format}</format>
                    </fhir.update>
                </case>
                <default/>
            </switch>
            <log level="full" separator=","/>
            <send/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
    <resource methods="POST" url-mapping="/delete">
        <inSequence>
            <property expression="json-eval($.base)" name="base" scope="default" type="STRING"/>
            <property expression="json-eval($.resourceType)" name="type" scope="default" type="STRING"/>
            <property expression="json-eval($.format)" name="format" scope="default" type="STRING"/>
            <property expression="json-eval($.idToDelete)" name="idToDelete" scope="default" type="STRING"/>
            <fhir.init>
                <base>http://hapi.fhir.org/baseR4</base>
            </fhir.init>
            <switch source="get-property('transport','Content-Type')">
                <case regex="application/json">
                    <property name="format" scope="default" type="STRING" value="json"/>
                    <fhir.delete>
                        <type>{$ctx:type}</type>
                        <idToDelete>{$ctx:idToDelete}</idToDelete>
                    </fhir.delete>
                </case>
                <case regex="application/xml">
                    <property name="format" scope="default" type="STRING" value="xml"/>
                    <fhir.delete>
                        <type>{$ctx:type}</type>
                        <idToDelete>{$ctx:idToDelete}</idToDelete>
                    </fhir.delete>
                </case>
                <default/>
            </switch>
            <log level="full" separator=","/>
            <send/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>
To learn about supported operations and their parameters, please refer to FHIR connector reference.

  1. Now we can export the imported connector and the API into a single CAR application. The CAR application is what we are going to deploy during server runtime.

Deployment

Follow these steps to deploy the exported CApp in the Enterprise Integrator Runtime.

Deploying on WSO2 Enterprise Integrator 7

You can copy the composite application to the /repository/deployment/server/carbonapps folder and start the server. Micro Integrator will be started and the composite application will be deployed. You can further refer to the application deployed through the CLI tool. You can download the CLI tool from here from the Other Resources section. Make sure you first export the PATH as below.

  $ export PATH=/path/to/mi/cli/directory/bin:$PATH
  1. Log in to Micro Integrator using the following command.

    ./mi remote login
  2. Provide default credentials admin for both username and password.

  3. In order to view the APIs deployed, execute the following command.

    ./mi api show
Click here for instructions on deploying on WSO2 Enterprise Integrator 6
  1. You can copy the composite application to the /repository/deployment/server/carbonapps folder and start the server.

  2. WSO2 EI server starts and you can login to the Management Console https://localhost:9443/carbon/ URL. Provide login credentials. The default credentials will be admin/admin.

  3. You can see that the API is deployed under the API section.

Testing

Invoke the API as shown below using the curl command. Curl Application can be downloaded from here.

  1. Add patient information.

Sample Request

curl -v POST -d 
'  {  "resourceType": "Patient",
        "name": [{"family": "Jhone","given": ["Winney","Rodrigo"]}]
   }' "http://localhost:8290/resources/create" -H "Content-Type:application/json" 
Expected Response:

<jsonObject>
    <resourceType>Patient</resourceType>
    <id>698021</id>
     <meta>
       <versionId>1</versionId>
       <lastUpdated>2020-03-24T07:57:14.506+00:00</lastUpdated>
     </meta>
      <text>
        <status>generated</status>
        <div>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div class="hapiHeaderText"&gt;Winney Rodrigo &lt;b&gt;JHONE &lt;/b&gt;&lt;/div&gt;&lt;table class="hapiPropertyTable"&gt;&lt;tbody/&gt;&lt;/table&gt;&lt;/div&gt;</div>
      </text>    
      <name>
         <family>Jhone</family>
         <given>Winney</given>
         <given>Rodrigo</given>
     </name>
</jsonObject>
  1. Read patient information.

Sample Request

curl -v POST -d 
'  {  
     "resourceType": "Patient"
   }' "http://localhost:8290/resources/read" -H "Content-Type:application/json"        
Expected Response:

It will retrieve all the existing resources in the FHIR server.

  1. Read specific patient information.

Sample Request

curl -v POST -d 
'{
    "resourceType":"Patient",
    "id":"698021"
 }' "http://localhost:8290/resources/readSpecificResourceById" -H "Content-Type:application/json"            
Expected Response:

<jsonObject>
       <resourceType>Patient</resourceType>
          <id>698021</id>
           <meta>
           <versionId>1</versionId>
           <lastUpdated>2020-03-24T07:57:14.506+00:00</lastUpdated>
           </meta>
           <text>
              <status>generated</status>
              <div>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div class="hapiHeaderText"&gt;Winney Rodrigo &lt;b&gt;JHONE &lt;/b&gt;&lt;/div&gt;&lt;table class="hapiPropertyTable"&gt;&lt;tbody/&gt;&lt;/table&gt;&lt;/div&gt;</div>
           </text>
            <name>
               <family>Jhone</family>
               <given>Winney</given>
               <given>Rodrigo</given>
            </name>
</jsonObject>
4. Update patient information.

Sample Request

   curl -v POST -d 
      '{
          "resourceType":"Patient",
          "idToUpdate":"597079",
          "name":[
             {
                "family":"Marry",
                "given":[
                   "Samsong",
                   "Perera"
                ]
             }
          ]
       }' "http://localhost:8290/resources/update" -H "Content-Type:application/json"   
Expected Response:

<jsonObject>
      <resourceType>Patient</resourceType>
      <id>597079</id>
      <meta>
         <versionId>1</versionId>
         <lastUpdated>2020-03-24T07:57:14.506+00:00</lastUpdated>
      </meta>
      <text>
         <status>generated</status>
         <div>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;div class="hapiHeaderText"&gt;Winney Rodrigo &lt;b&gt;JHONE &lt;/b&gt;&lt;/div&gt;&lt;table class="hapiPropertyTable"&gt;&lt;tbody/&gt;&lt;/table&gt;&lt;/div&gt;</div>
      </text>
      <name>
         <family>Marry</family>
         <given>Samsong</given>
         <given>Perera</given>
      </name>
   </jsonObject>
5. Delete patient information.

Sample Request

curl -v POST -d 
'{
   "resourceType":"Patient",
   "idToDelete":"597079",
 }' "http://localhost:8290/resources/delete" -H "Content-Type:application/json" 
Expected Response:

   <jsonObject>
      <resourceType>OperationOutcome</resourceType>
      <text>
         <status>generated</status>
         <div>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;h1&gt;Operation Outcome&lt;/h1&gt;&lt;table border="0"&gt;&lt;tr&gt;&lt;td style="font-weight: bold;"&gt;INFORMATION&lt;/td&gt;&lt;td&gt;[]&lt;/td&gt;&lt;td&gt;&lt;pre&gt;Successfully deleted 1 resource(s) in 46ms&lt;/pre&gt;&lt;/td&gt;


                         &lt;/tr&gt;
                     &lt;/table&gt;
                 &lt;/div&gt;</div>
      </text>
      <issue>
         <severity>information</severity>
         <code>informational</code>
         <diagnostics>Successfully deleted 1 resource(s) in 46ms</diagnostics>
      </issue>
   </jsonObject>
This demonstrates how the WSO2 EI FHIR connector works.

What's next

Top