Oystehr
Core Documentation
Migration Guide

Migration Guide

This page contains instructions on how to migrate to the latest version of the Oystehr SDK. When a new major version is released, we will add a new section, leaving the guides for older versions below.

Migrating to v4

The v4 version of the SDK includes a reorganization of the eRx module to prioritize the new eRx Service v3. The eRx Service v1 and eRx Service v2 functionality has been preserved in the erxV1 and erxV2 modules.

v4 also adds stricter types when interacting with the FHIR service. Function parameters now require explicit types in cases where the FhirResource subtype cannot be inferred. This change helps to prevent bugs, like accidentally querying one resource type while claiming to query another.

Continuing to use eRx Service v1 and v2 functionality

eRx Service v1 and v2 are deprecated. Please migrate to the new eRx Service v3 functions. eRx Service v1 and v2 functionality will be removed in a future release.

eRx Service v1

Use the new erxV1 module to access the v1 functionality.

import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
const medications = await oystehr.erxV1.medicationSearch({ name: 'acetaminophen' })

eRx Service v2

The eRx Service v2 medication search has moved to the erxV2 module.

import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
const medications = await oystehr.erxV2.medicationSearch({ name: 'acetaminophen' })

Transitioning to the new eRx Service

The new eRx Service v3 functionality is now available in the erx module. The new service has a broader array of functionality and ties into the SureScripts ePrescribing network.

Function names have been changed to be more accurate and consistent — for example, allergySearch is now searchAllergens.

There are a number of breaking changes in the new service, including:

Handling new FHIR type safety requirements

When a FHIR resource type cannot be inferred from the function parameters, you must now provide an explicit type for the resourceType field on all FHIR service function parameters. This change helps to prevent accidentally querying one resource type while claiming to query another.

Most uses of the FHIR service will not require a change, since they operate on one resource at a time in an explicit way. However, some usage patterns will require changes to meet the new type safety requirements.

Extracting resource type from a FHIR reference

If you extract the resource type and ID out of a FHIR reference (resourceType/id), you will need to explicitly type the resourceType field in the function parameters. Common applications for this pattern are when manipulating a resource referenced by a different resource, or when using a FHIR reference inside an URL to create a permanent link to a resource.

import Oystehr from '@oystehr/sdk';
import { Patient, RelatedPerson, Organization } from 'fhir/r4b'; // import the FHIR resource types you expect to use
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
 
const guarantorRef = 'Patient/b99e32bc-729d-45df-892e-7f637fb1eaa4'; // example string-encoded FHIR reference
const [guarantorType, guarantorId] = guarantorRef.split('/');
 
const guarantor = await oystehr.fhir.get<Patient | RelatedPerson | Organization>({ // use a union type for the expected resource types
  resourceType: guarantorType as 'Patient' | 'RelatedPerson' | 'Organization', // explicitly type the resourceType
  id: guarantorId,
});

Using a function that handles all possible FHIR resource types

If you have created a function that handles all possible FHIR resource types, or uses the FhirResource type, you will need to explicitly type the resourceType field in the function parameters.

To handle this in-line without generics, use FhirResource['resourceType']:

import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
 
async function getFhirResource(oystehr: Oystehr, resourceType: string, id: string) {
  return oystehr.fhir.get<T>({
    resourceType: resourceType as FhirResource['resourceType'], // explicitly type the resourceType
    id,
  });
}

A more type-safe version of this function would use generics to infer the resource type from the resourceType parameter:

import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
 
async function getFhirResource<T extends FhirResource>(oystehr: Oystehr, resourceType: T['resourceType'], id: string): Promise<T> {
  return oystehr.fhir.get<T>({
    resourceType,
    id,
  });
}

Migrating to v3

The v3 version of the SDK offers a number of new features — explicit parameter and return types for all functions, automatic and configurable retries, and more.

This is also the first release under the @oystehr/sdk package.

Initialization and Use

Initialization has changed in v3 to use a single class instance. Pass your configuration to the constructor function and use the resulting instance as your entrypoint to all Oystehr services.

import { Patient } from 'fhir/r4b';
 
// v1
import { AppClient, FhirClient } from '@zapehr/sdk';
const fhirClient = new FhirClient({
  accessToken: '<your_access_token>',
});
const patient = await fhirClient.createResource<Patient>({ resourceType: 'Patient '});
const appClient = new AppClient({
  accessToken: '<your_access_token>',
});
const app = await appClient.getApplication('a7e25b8e-22fb-4ba2-ba9f-d0ec47825811');
 
// v2
import zapehr from '@zapehr/sdk';
zapehr.init({
  ZAPEHR_ACCESS_TOKEN: '<your_access_token>', // can also be provided from an environment variable
});
const patient = await zapehr.fhir.createResource<Patient>({ resourceType: 'Patient '});
const app = await zapehr.project.application.get('a7e25b8e-22fb-4ba2-ba9f-d0ec47825811');
 
// v3
import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
const patient = await oystehr.fhir.create<Patient>({ resourceType: 'Patient '});
const app = await oystehr.application.get('a7e25b8e-22fb-4ba2-ba9f-d0ec47825811');

Access to non-FHIR Services

The structure of the library has been flattened to remove the project layer.

// v2
import zapehr from '@zapehr/sdk';
zapehr.init({
  ZAPEHR_ACCESS_TOKEN: '<your_access_token>', // can also be provided from an environment variable
});
const app = await zapehr.project.application.get('a7e25b8e-22fb-4ba2-ba9f-d0ec47825811');
//                       ^ all non-FHIR services under `project`
 
// v3
import Oystehr from '@oystehr/sdk';
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
const app = await oystehr.application.get('a7e25b8e-22fb-4ba2-ba9f-d0ec47825811');
//                       ^ all non-FHIR services at top level

FHIR Search

The default return type for FHIR search has been changed to Bundle<FhirResource> to better match the FHIR search specification. Search has also been consolidated to a single method. An unbundle() helper has been added to provide access to an array of FhirResource.

// v3
import { Patient } from 'fhir/r4b';
import Oystehr from '@oystehr/sdk';
 
const oystehr = new Oystehr({
  accessToken: '<your_access_token>',
});
const bundle/*: Bundle<Patient>*/ = await oystehr.fhir.search<Patient>({
 
  resourceType: 'Patient',
  params: [
    {
      name: 'name:exact',
      value: 'Anna,Maria,Juanita',
    },
  ],
});
const patients/*: Patient[]*/ = bundle.unbundle();
 
const morePatients/*: Patient[]*/ = (await oystehr.fhir.search<Patient>({
  resourceType: 'Patient',
  params: [
    {
      name: 'name:exact',
      value: 'Anna,Maria,Juanita',
    },
  ],
})).unbundle();