Important: The JavaScript SDK is a working example of how to wrap and use the DexCare API. The SDK is not currently among the supported products of DexCare - but can be used as a toolkit to gain understanding of the DexCare API and accelerate development.

Getting Started

This section explains how to install and use the DexCare JavaScript SDK in your applications.

Installing the SDK

The DexCare JavaScript SDK is available as an npm module in DexCare’s NPM respository on Github Packages. NPM modules used by an application are defined in that application’s package.json file.

In order to install this SDK you may need to create or modify your .npmrc file to specify the location of the DexCare NPM repository. Adding the following line to .npmrc allows the npm tool to access repositories in DexCare’s organization:

@DexCare:registry=https://npm.pkg.github.com/

For more details please see the “installing a package” section in the Github Packages documentation.

If you use a personal access token (PAT) to access Github Packages and your PAT does not have read:packages permission (either directly specified or by inheritance) then you may need to update your PAT to include this permission. See the Scopes for OAuth apps section in the Github Packages documentation for details.

If the Dexcare JS SDK is specified in your package.json file then you can issue the npm install command in your project’s root directory to install the SDK. In addition, you can use one of the following two command-line methods to download the SDK for use by your application:

  • “Local” installation using the npm install --save @DexCare/dexcare-js-sdk command, executed from within the directory where your package.json file is located. This installs the SDK and adds it your package.json file as a dependency. Alternately, you can manually define the SDK and its version info in your package.json file, and then use the npm install command to install the SDK.
  • “Global” installation using the npm install --global @DexCare/dexcare-js-sdk command. This installs the SDK to your global NPM folder on your system.

Generally, DexCare recommends using the “local” installation method. This ensures that other applications on your system that might use the SDK are not affected.

For more information about the npm-install command, please see the command-line documentation at docs.npmjs.com.

Initializing the SDK

To initialize the SDK for use, use the DexCareSDKFactory.newInstance() method. This method takes two arguments: an SDK version (to allow for easy future upgrades), and a reference to a DexCareConfiguration object that describes your DexCare configuration. Currently, the version parameter is always set to V1.

Your DexCareConfiguration should contain the following information:

Parameter name Description Required?
apiEndpoint the full DNS name of your api endpoint. Yes
ecvEndpoint the full DNS name of your ecv endpoint. Yes
schedulingEndpoint the full name of your scheduling workflow endpoint. Yes
practiceId your practice ID For virtual scheduling mode only
brand your brand No
domain your domain Yes

This information is defined by you, in collaboration with your DexCare support team.

For example:

const sdkConfiguration: DexCareConfiguration = {
    apiEndpoint: "api.care.my-healthcare-system.com",
    ecvEndpoint: "ecv.care.my-healthcare-system.com",
    schedulingEndpoint: "scheduling.care.my-healthcare-system.com",
    practiceId: "12345",
    brand: "MyGreatBrand",
    domain: "MyGreatDomain"
}

const sdk = DexCareSDKFactory.newInstance(SDKVersion.V1, sdkConfiguration);

Developing Applications

The JavaScript SDK provides two mechanisms for accessing DexCare services. The method you choose will depend on the complexity of your requirements.

High-Level Fluent SDK

Almost all of DexCare’s functionality is available through a flexible, easy-to-use set of high-level methods. These methods are based on a “fluent” design pattern, and are suitable for the majority of retail and virtual use cases.

The Fluent SDK methods are founded on two concepts: selectors and execution contexts. The execution context provides key functions that facilitate access to DexCare services and data:

  • controlling how requests are structured so that only valid requests can be made;
  • validating your request before retrieving any data or invoking any services, in order to ensure that all required data is present;
  • aggregating multiple calls to the REST API, where possible, in order to optimize the end user experience;
  • providing filtering capabilities that give a high level of control over which data is returned.

Selectors are used to define the data you wish to retrieve. That data is returned in the execution context, where it can be accessed by applications.

To use the Fluent SDK methods, follow these steps:

  • Define any configuration information required for your application. This might include information such as the healthcare system’s brand, the user’s latitude and longitude, and other info required by your application or the DexCare SDK.
  • Instantiate an instance of the SDK, and provide it with details about your DexCare environment.
  • Use the SDK’s getRetailSchedulingContextBuilder() or getVirtualSchedulingContextBuidler() method to create an execution context that is appropriate for your application.
  • When the builder is created, use its parameters to define the scope of information you want to retrieve from DexCare, then use the build() function to perform parameter validation and issue the appropriate requests to the DexCare service.
  • Use the execution context to access the returned data.

Check the Fluent SDK Reference for details on the various methods and parameters available.

Fluent SDK example: Retrieving retail appointment slots

The following provider-agnostic scheduling example retrieves appointment time slots for all providers at all departments within a given radius of a specified location. Time slots for all possible visit types are included.

// Define the SDK configuration
const sdkConfiguration: DexCareConfiguration = {
    apiEndpoint: "api.care.my-healthcare-system.com",
    ecvEndpoint: "ecvcare..my-healthcare-system.com",
    schedulingEndpoint: "scheduling.care.my-healthcare-system.com",
    practiceId: "12345",
    brand: "MyGreatBrand",
    domain: "MyDexCareDomain"
}

// Define the application configuration.
const appConfig = {
    brand: 'MyHealthcareSystem',
    clinicSearchCriteria: { lat: 45.5152, long: -122.6784, radius: 10 }
}

// Instantiate the SDK
const sdk: DexCareSDK = DexCareSDKFactory.newInstance(SDKVersion.V1, sdkConfiguration)

// Define the execution context, validate the request and retrieve the data. This context
// returns any retail department within the radius specified in the application config,
// and also retrieves appointment time slots for those locations.
let ctx: RetailExecutionContext;
try {
    ctx = await sdk.getRetailExecutionContextBuilder()
        .forBrand(appConfig.brand)
        .forDepartments(
            RetailDepartmentSelector
                .anyDepartmentWithin(
                    appConfig.clinicSearchCriteria.radius,
                    RadiusFilterUnits.MILES)
                .ofLocation(appConfig.clinicSearchCriteria.lat,
                    appConfig.clinicSearchCriteria.long)
                .build()
        )
        .withAppointmentSlots()
        .build();
} catch (error) {
    console.log(`Unable to retrieve time slots for departments: ${error.message}`);
}

// Are there any departments available?
if (!ctx.allDepartments || ctx.allDepartments.length === 0) {
    throw new Error('There are no available retail clinics at this time.');
}

// For example purposes, select the first returned department.
const selectedDepartment = ctx.allDepartments[0];

// Retrieve the available visit types for the selected department
const availableVisitTypes = ctx.getFilteredVisitTypes(selectedDepartment);

// For example purposes, select the first available visit type.
const visitType = availableVisitTypes[0];

Fluent SDK example: Retrieving virtual visit appointment slots

The following example retrieves virtual visit appointment time slots in the default practice for the California practice region. Wait times for all visit types are returned.

// Define the SDK configuration
const sdkConfiguration: DexCareConfiguration = {
    apiEndpoint: "api.care.my-healthcare-system.com",
    ecvEndpoint: "ecvcare..my-healthcare-system.com",
    schedulingEndpoint: "scheduling.care.my-healthcare-system.com",
    practiceId: "12345",
    brand: "MyGreatBrand",
    domain: "MyDexCareDomain"
}

// Define the application configuration.  
const appConfig = {
    practiceId: '12345',
    regionCode: 'CA',
    assignmentQualifiers: ['adult']
}

// Instantiate the SDK
const sdk: DexCareSDK = DexCareSDKFactory.newInstance(SDKVersion.V1, sdkConfiguration)

// Define the execution context, validate the request and retrieve the data.  This context 
// retrieves the information about virtual visits in the default practice and for the 
// specified region.
const ctx: VirtualExecutionContext =
    await this.sdk.getVirtualExecutionContextBuilder()
        .forRegion(
            VirtualRegionSelector
                .forDefaultPractice()
                .withRegionCode(appConfig.regionCode)
                .build()
        )
        .build();

// Retrieve wait time in active regions for all modalities (virtual, phone, or user-defined).
// If desired, you can retrieve the practice region definition for the specified region code 
// using `ctx.getPracticeRegions(regionCode)` in order to get additional information, such as 
// the visit price, busy message, etc.
const regionWaitTimeByModality = ctx.getWaitTimes({
    regionCode: appConfig.regionCode,
    assignmentQualifiers: appConfig.assignmentQualifiers,
    onlyActive: true
});

Low-level Methods

For more complex workflows, the complete set of DexCare functionality is available via low-level methods that allow direct access to the DexCare REST API. These are best suited to more complex workflows where the level of control provided by the API is needed.

The low-level methods reduce the work associated with using the REST API by handling basic parameter validation, facilitating error handling, and so on. Details on these methods can be found in the Low-level method reference.

To use the low-level SDK methods, follow these steps:

  • Instantiate an instance of the SDK, and provide it with details about your DexCare environment.
  • Invoke SDK methods found on the DexCareSDK class.

Low-level SDK example: Retrieving retail appointment slots

The following provider-agnostic scheduling example retrieves appointment time slots for all providers at all departments within a given radius of a specified location. Time slots for all possible visit types are included.

// Define the SDK configuration
const sdkConfiguration: DexCareConfiguration = {
    apiEndpoint: "api.care.my-healthcare-system.com",
    ecvEndpoint: "ecvcare..my-healthcare-system.com",
    schedulingEndpoint: "scheduling.care.my-healthcare-system.com",
    practiceId: "12345",
    brand: "MyGreatBrand",
    domain: "MyDexCareDomain"
}

// Define the application configuration.  
const appConfig = {
    practiceId: '12345',
    regionCode: 'CA',
    assignmentQualifiers: ['adult']
}

// Instantiate the SDK
const sdk: DexCareSDK = DexCareSDKFactory.newInstance(SDKVersion.V1, sdkConfiguration)

try {
    // Get a list of all departments within a specified radius of a given point.
    let departments: Department[] =
        await sdk.getAllDepartments(
            ClinicTypes.retail,
            true,               // only return active departments
            true,               // include time slots 
            appConfig.brand,
            new RadiusFilter(),
            { lat: 45.5152, long: -122.6784, radius: 10, unit: RadiusFilterUnits.MILES }
        );
        if (!departments || departments.length === 0) {
            throw new Error('There are no available retail clinics at this time.');
        }

        const selectedDepartment = departments[0];

        // Retrieve the available visit types for the selected department
        const availableVisitTypes = selectedDepartment.allowedVisitTypes;
        const visitType = availableVisitTypes[0];
} catch (error) {
    console.log(`An error occurred: ${error.message}`);
}

Low-level SDK example: Retrieving virtual visit appointment slots

The following example retrieves virtual visit appointment time slots in the default practice for the California practice region. Wait times for all visit types are returned.

// Define the SDK configuration
const sdkConfiguration: DexCareConfiguration = {
    apiEndpoint: "api.care.my-healthcare-system.com",
    ecvEndpoint: "ecvcare..my-healthcare-system.com",
    schedulingEndpoint: "scheduling.care.my-healthcare-system.com",
    practiceId: "12345",
    brand: "MyGreatBrand",
    domain: "MyDexCareDomain"
}

// Define the application configuration.  
const appConfig = {
    practiceId: '12345',
    regionCode: 'CA',
    assignmentQualifiers: ['adult']
}

// Instantiate the SDK
const sdk: DexCareSDK = DexCareSDKFactory.newInstance(SDKVersion.V1, sdkConfiguration)

try {
    let availAndWaitTime: WaitTimeAvailability[] = 
            await sdk.getRegionAvailabilityAndWaitTime(
                        {
                            regionCodes: [ appConfig.regionCode ],
                            practiceId: '12345',
                            assignmentQualifiers: appConfig.assignmentQualifiers
                        }
                );

    availAndWaitTime.forEach(waitTime => {
        if (waitTime.available) {
            // process this wait time entry
        } else {
            // Using the default market, retrieve the practice region to get the open 
            // dates/times, busy message, etc.  Note that this request gets ALL practice regions 
            // and then filters locally.
            const practiceRegion = await getPracticeRegionByRegionCodeAndMarket(appConfig.regionCode);
            // Process the practice regions to display open/close times, busy message, etc.
        }
    });
} catch (error) {
    console.log(`An error occurred: ${error.message}`);
}