@hmsconnect/hmshealthapi

0.4.3 • Public • Published

HMS OpenHealth APIs

This is the SDK for HMS OpenHealth APIs to connect and get data from HMSConnect.

Installation

$ npm i @hmsconnect/hmshealthapi --save

HMS APIs Usage

Using NodeJS/CLI

Initial/Config SDK

// Declare HMS instance object
const hmshealthapi = require('@hmsconnect/hmshealthapi');

let tokens = {
  username: '[YOUR_USER_NAME]',
  password: '[YOUR_PASSWORD]',
  client_id: '[YOUR_CLIENT_ID]'
};

// Create instance
let hms = hmshealthapi();

// Using the instance
// ...

Sandbox Configuration

You can config specific data source via method name SetConfig. For main attributes of the config, please refer to JSON object below :

{
  host: '[DATA_SOURCE_IP_OR_HOSTNAME]',
  endpoints: {
    get_domain_resource : '/sandbox/[DATA_SOURCE]/[SOURCE_VERSION]',
    get_version : '/sandbox/version'
  }
}

Where

  • host - it can be IP with port number or host name
  • endpoints.get_domain_resource - an endpoint to request data in specific domain resource. The endpoint MUST add prefix with /.
  • endpoints.get_version - current sandbox API version (may not relate with lib version)

For DATA_SOURCE, we provide 2-sources including :

  • api for data source name HMS
  • sfhir for data source name SmartFHIR

SOURCE_VERSION is version of data source, including :

  • HMS has only version v2
  • SmartFHIR has only version stu3

Testing sandbox connection by checking version

let tokens = {
  username: '[YOUR_USER_NAME]',
  password: '[YOUR_PASSWORD]',
  client_id: '[YOUR_CLIENT_ID]'
};

let hms = hmshealthapi();
hms.Initial(tokens, (error, response) => {
  
  if(error) {
    console.log('Initial error : ', error);
  } else {
    console.log('response :', response);

    // Config data source
    hms.SetConfig({
      host: '[DATA_SOURCE_IP_OR_HOSTNAME]',
      endpoints: {
        get_domain_resource : '/sandbox/[DATA_SOURCE]/[SOURCE_VERSION]',
        get_version : '/sandbox/version'
      }
    });
  }

});

Searching with request URL style

hms.Initial(tokens, (error, response) => {

  if(error) {
    console.log('Initial error : ', error);
  } else {

    // ...

    // -----------------------------------------------------
    // ------------------ HMS Data source ------------------
    // -----------------------------------------------------

    // Config data source
    hms.SetConfig({
      host: '[DATA_SOURCE_IP_OR_HOSTNAME]',
      endpoints: {
        get_domain_resource : '/sandbox/api/v2',
        get_version : '/sandbox/version'
      }
    });

    try {

      const headers = {
        Authorization: `Bearer ${response.access_token ? response.access_token : ''}`
      };

      console.log('Header : ', headers)

      hms.get('practitioner', headers, 'name.givenName:contain="Rozelle 105418"&sort=-identifier.start')
      .then((response) => { console.log('Searching with request URL:', JSON.stringify(response, null, 2)); })
      .catch((err) => { console.log('Error :', err); });

    } catch(err) {
      console.log(err)
    }



    // -----------------------------------------------------
    // --------------- SmartFHIR Data source ---------------
    // -----------------------------------------------------

    // Config for SmartFHIR(vSTU3) data source
    hms.SetConfig({
      host: '[DATA_SOURCE_IP_OR_HOSTNAME]',
      endpoints: {
        get_domain_resource : '/sandbox/sfhir/stu3',
        get_version : '/sandbox/version'
      }
    });

    try {
      
      const headers = {
        Authorization: `Bearer ${response.access_token ? response.access_token : ''}`
      };

      console.log('Header : ', headers)

      hms.get('patient', headers, 'id=0debf275-d585-4897-a8eb-25726def1ed5')
      .then((response) => { console.log('Searching with request URL:', JSON.stringify(response, null, 2)); })
      .catch((err) => { console.log('Error :', err); });

    } catch(err) {
      console.log(err)
    }
  }

});
Example output for HMS data source :

Searching with request URL:{
  "error": null,
  "message": "Query Success",
  "page": 1,
  "limit": 10,
  "total": 9,
  "data": [
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.......A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "105......A",
          "start": "2013-10-11",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "2.......7",
      "name": [
        {
          "text": "นพ. Rozelle 10.........A",
          "prefix": "นพ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "0...........7"
        }
      ],
      "qualification": [
        {
          "code": "28",
          "display": "Part time"
        }
      ],
      "specialty": [
        {
          "code": "SURG",
          "display": "ศัลยศาสตร์ (SURGERY)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-08-13",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "ท.1.......9",
      "name": [
        {
          "text": "ทพ. Rozelle 10.........A",
          "prefix": "ทพ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "08.......11"
        }
      ],
      "qualification": [
        {
          "code": "2",
          "display": "แพทย์นอกเวลา (แพทย์เวร)"
        }
      ],
      "specialty": [
        {
          "code": "DEN",
          "display": "ทันตกรรม (DENTIST)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-06-29",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "3.......7",
      "name": [
        {
          "text": "นพ. Rozelle 10.........A",
          "prefix": "นพ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "08.........6"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "ORT",
          "display": "กระดูก (ORTHOPAEDIST)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-06-26",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "3........9",
      "name": [
        {
          "text": "พญ. Rozelle 10.........A",
          "prefix": "พญ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": null
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "08........0"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "NEUM",
          "display": "อายุรกรรมประสาท (NEUROLOGIST)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-06-21",
          "end": "2017-12-20"
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "4.......0",
      "name": [
        {
          "text": "พญ. Rozelle 10.........A",
          "prefix": "พญ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "08........4"
        }
      ],
      "qualification": [
        {
          "code": "28",
          "display": "Part time"
        }
      ],
      "specialty": [
        {
          "code": "GP ",
          "display": "เวชปฎิบัติทั่วไป  (GENERAL PRACTICE)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-06-18",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "3........2",
      "name": [
        {
          "text": "พญ. Rozelle 10.........A",
          "prefix": "พญ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "08.........6"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "MED",
          "display": "อายุรศาสตร์ทั่วไป (INTERNAL MEDICINE)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-05-30",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "3........3",
      "name": [
        {
          "text": "นพ. Rozelle 10.........A",
          "prefix": "นพ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "0..........8"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "NEUM",
          "display": "อายุรกรรมประสาท (NEUROLOGIST)"
        },
        {
          "code": "MED",
          "display": "อายุรศาสตร์ทั่วไป (INTERNAL MEDICINE)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-05-07",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "3......1",
      "name": [
        {
          "text": "พญ. Rozelle 10.........A",
          "prefix": "พญ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "0........5"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "MED",
          "display": "อายุรศาสตร์ทั่วไป (INTERNAL MEDICINE)"
        },
        {
          "code": "GI",
          "display": "ทางเดินอาหาร (GASTROENTEROLOGIST)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    },
    {
      "resourceType": "Practitioner",
      "employeeId": null,
      "careProviderId": "10.........A",
      "identifier": [
        {
          "type": "care_provider_id",
          "value": "10.........A",
          "start": "2013-03-29",
          "end": null
        }
      ],
      "active": true,
      "gender": "unknown",
      "birthDate": "",
      "licenseNo": "33.....7",
      "name": [
        {
          "text": "พญ. Rozelle 10.........A",
          "prefix": "พญ.",
          "givenName": "Rozelle 10.........A",
          "middleName": null,
          "familyName": "Scala 10.........A"
        }
      ],
      "telecom": [
        {
          "type": "phone",
          "value": "0.......998"
        }
      ],
      "qualification": [
        {
          "code": "1",
          "display": "แพทย์ประจำ"
        }
      ],
      "specialty": [
        {
          "code": "PHYR",
          "display": "เวชศาสตร์ฟื้นฟู (PHYSICAL & REHABILITATION MEDICINE)"
        },
        {
          "code": "REH",
          "display": "กายภาพ (PHYSIAPRIST)"
        }
      ],
      "role": [
        {
          "code": null,
          "display": null
        }
      ],
      "location": [],
      "organization": {
        "codeNumber": "078",
        "codeName": "YMH",
        "name": null,
        "latitude": null,
        "longitude": null
      },
      "created": "2020-01-14T15:02:05",
      "updated": ""
    }
  ]
}

IMPORTANT : Now HMS OpenHealth API support searching with request URL only

2020-04-23 : [DEPRECATED] We plan to unused "getVersion()" after 2020-04-22

The function using for get latest version of sandbox, we plan to use API instead of built-in method.

2020-04-02 : [PENDING] Pending authentication method by using "license key" (Now we using OAuth2 instead)

let tokens = {
  // Sandbox license token
  license:'9b55b572-154e-3739-bebd-56ca7e2c5aa8',
    
  // Sandbox didn't require token below
  client_id: '',
  client_secret: ''
};

let hms = hmshealthapi();
hms.Initial(tokens, (error, response) => {
  if(error) {
    console.log('Initial : ', error);
  } else {
    console.log('Initial : ', response);

    // Your app here
  }
});

Searching with request URL style

hms.Initial(tokens, (error, response) => {

  if(error) {
    console.log('Initial : ', error);
  } else {

    // ...

    const headers = {
        Authorization: `Bearer ${response.access_token ? response.access_token : ''}`
    };

    hms.get('practitioner', headers, 'name.givenName:contain="Rozelle 105418"&sort=-identifier.start')
    .then((response) => { console.log('Searching with request URL:', JSON.stringify(response, null, 2)); })
    .catch((err) => { console.log('Error :', err); });
  }

});
2019-11-12 : [DEPRECATED] Searching with request body style : Find match

sb
.findMatch('patient', { hn:'7.........51' })
.then((response) => { console.log('search with findMatch:', response.data) })
.catch((err) => { console.log('findMatch:', err) })
2019-12-01 : [DEPRECATED] Searching with request body style : Contains

sb
.contains(

  // Specific domain resource
  'encounter', 

  // In case, you remember some text on that field(hn).
  { hn:'952151' }, 

  // Search option
  { 
    page:1,                 // <----- support pagination feature
    limit:10,               // <----- limit record per page
                            //        (by default, minimum is 10)
    sort: { 
      ['period.start']:1    // <----- sort specific field with 
                            //         -  1 is "ascending"
                            //         - -1 is "descending"
    } 
  }
)
.then((response) => { console.log('search with contains :', response.data) })
.catch((err) => { console.log('findMatch:', err) })

UMD

Our SDK support client side too, please refer to example

Contribution

At the end of each development phase of the API, you MUST pack the API by using webpack both development and production.

IMPORTANT : DON'T FORGET CHANGING VERSION IN package.json BASED ON [MAJOR].[MINOR].[PATCH].

{
  "name": "@hmsconnect/hmshealthapi",
  "version": "1.0.4",      <---------------- HERE
  "main": "src/App.es6",
  "scripts": {
    ...
  }
  .
  .
  .
}

Let's pack the API via command:

# For development, hmshealthapi.js
$ npm run build:dev

# and

# For production (with minimize code), hmshealthapi.min.js
$ npm run build:prod

After that we will publish HMSHealthAPIs to npm server by calling our custom script to publish it:

$ sh publish.sh

See result : https://www.npmjs.com/package/@hmsconnect/hmshealthapi

License

MIT

Package Sidebar

Install

npm i @hmsconnect/hmshealthapi

Weekly Downloads

0

Version

0.4.3

License

MIT

Unpacked Size

43.3 kB

Total Files

23

Last publish

Collaborators

  • hmsconnect
  • patharagls
  • patharanor