Skip to content

Commit

Permalink
Support for VSAC FHIR API (#28)
Browse files Browse the repository at this point in the history
* Add support for using the FHIR VSAC endpoint (via a flag to the CodeService constructor)
* Refactor code to reduce duplication and minimize footprint of different APIs (FHIR vs SVS).
* Switch promise handling to use async / await where it makes sense
* Update dependencies
  • Loading branch information
cmoesel authored Oct 16, 2023
1 parent 16349f5 commit 3905094
Show file tree
Hide file tree
Showing 21 changed files with 1,885 additions and 591 deletions.
5 changes: 5 additions & 0 deletions .mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
file: ['./test/setup.js']
};
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@ valueset "Diabetes": 'https://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.
The embedded version, however, is only supported for the canonical URL form of value sets. It is not supported for URN
or OID identifiers.

## Credentials Required
## UMLS API Key Required

This library requires that the credentials of a valid UMLS account be provided to it. If you do not have an UMLS
account, you can request one here: https://uts.nlm.nih.gov/license.html
This library requires a valid UMLS API key. If you do not have an UMLS account, you can request one here:
https://uts.nlm.nih.gov/license.html

## SVS and FHIR APIs

The CQL Execution Code Service supports the Value Set Authority Center's
[SVS API](https://www.nlm.nih.gov/vsac/support/usingvsac/vsacsvsapiv2.html) and
[FHIR API](https://www.nlm.nih.gov/vsac/support/usingvsac/vsacfhirapi.html). The SVS API is used by default, as our
internal testing has shown it to be more performant than the FHIR API. The chosen API can be switched by passing
in the `useFHIR` flag to the `CodeService` constructor.

# Setting Up the Environment

Expand Down Expand Up @@ -65,8 +73,8 @@ provided via the `UMLS_API_KEY` environment variable.

The `ensureValueSetsWithAPIKey` and `ensureValueSetsInLibraryWithAPIKey` functions are the only functions that attempt
to download value sets from VSAC. Before they make a request to VSAC, they will check the cache. If the value set is
already in the cache, they will not make a request to VSAC. Otherwise, they will use VSAC's SVS2 API to download the
expanded codes from the value set.
already in the cache, they will not make a request to VSAC. Otherwise, they will use VSAC's SVS2 API or FHIR API
to download the expanded codes from the value set.

The `findValueSet` and `findValueSets` functions (including the legacy `findValueSetsByOid` function) do not reach out
to VSAC, so implementations should call `ensureValueSetsInLibraryWithAPIKey` or `ensureValueSetsWithAPIKey` before
Expand Down
24 changes: 19 additions & 5 deletions manual-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,46 @@ const VALUESET = {
name: 'HDL Cholesterol',
id: '2.16.840.1.113883.3.464.1003.104.12.1013'
};
// Use this value set if you want something > 1000 codes
// const VALUESET = {
// name: 'Diabetes mellitus',
// id: '2.16.840.1.113762.1.4.1078.405'
// };

async function main() {
if (env['UMLS_API_KEY'] == null) {
console.error('This test requires you to set the UMLS_API_KEY environment variable');
process.exit(1);
}
await run(false); // SVS
console.log();
await run(true); // FHIR
}

const codeService = new CodeService('manual-test-vsac-cache', false);
console.log(`CALL: codeService.findValueSet(${VALUESET.id})`);
async function run(useFHIR) {
const api = useFHIR ? 'FHIR' : 'SVS';
const start = new Date();
const codeService = new CodeService('manual-test-vsac-cache', false, useFHIR);
console.log(`${api} CALL: codeService.findValueSet(${VALUESET.id})`);
console.log('EXPECT: undefined');
let found = codeService.findValueSet(VALUESET.id);
console.log(`RESULT: ${found}`);
console.log();
console.log(
`CALL: codeService.ensureValueSetsWithAPIKey(['${JSON.stringify(
`${api} CALL: codeService.ensureValueSetsWithAPIKey(['${JSON.stringify(
VALUESET
)}'], env['UMLS_API_KEY'], false);`
);
await codeService.ensureValueSetsWithAPIKey([VALUESET], env['UMLS_API_KEY'], false);
console.log('EXPECT: <void>');
console.log(`RESULT: <void>`);
console.log();
console.log(`CALL: codeService.findValueSet(${VALUESET.id})`);
console.log(`${api} CALL: codeService.findValueSet(${VALUESET.id})`);
found = codeService.findValueSet(VALUESET.id);
console.log('EXPECT: <valueSet w/ two codes>');
console.log(`RESULT: ${JSON.stringify(found, null, 2)}`);
console.log(`RESULT: ${JSON.stringify(found, null, 2)}\n(${found.codes.length} codes)`);
console.log();
console.log(`${api} TOTAL TIME: ${new Date() - start} ms`);
}

main().catch(e => console.error(e));
Loading

0 comments on commit 3905094

Please sign in to comment.