-
Notifications
You must be signed in to change notification settings - Fork 124
Profile
We are currently focused on being fully compliant with the US Core implementation of FHIR. In order to do this, we need to offer support for many resource profiles. On this Wiki page you will find all the current resource profiles we are supporting and instructions for how you can use them in an app leveraging node-fhir-server-core
.
Supporting a profile in your application using node-fhir-server-core
is very easy. We take care of a lot of the hard work for you like defining arguments, sanitizing arguments, checking scopes, token and user validation, defining routes, and converting the data into compliant US Core resources. All profiles are opt-in only and to tell the core server that you want to support a particular profile, you just need to provide the service that conforms to the profiles interface and the versions you intend to support. There are other configuration options available which will be covered below.
Here is a simple example of setting up a config object to be used in node-fhir-server-core
. In particular, pay attention to the profiles section in config.js
.
// config.js
const { VERSIONS } = require('@asymmetrik/node-fhir-server-core').constants;
module.exports = {
profiles: {
// These profile keys, e.g. patient, observation, etc
// are defined in the Profile Configuration section below
patient: {
service: path.resolve('./src/patient/patient.service.js'),
versions: [ VERSIONS.STU3 ]
}
}
};
// app.js
// Assuming you have already installed all the required dependencies
const FHIRServer = require('@asymmetrik/node-fhir-server-core');
const config = require('./config');
let server = FHIRServer.initialize(config);
server.listen(3000, () => server.logger.verbose('Server is up and running!'));
We support the following profiles. The profile_name
can be substituted anywhere in this document you see profile_name
and the profile_key
is the property you use in the profiles config object.
profile_name | profile_key |
---|---|
AllergyIntolerance | allergyintolerance |
CarePlan | careplan |
CareTeam | careteam |
Condition | condition |
Device | device |
DiagnosticReport | diagnosticreport |
Goal | goal |
Immunization | immunization |
Location | location |
Medication | medication |
MedicationRequest | medicationrequest |
MedicationStatement | medicationstatement |
Observation | observation |
Organization | organization |
Patient | patient |
Practitioner | practitioner |
Procedure | procedure |
Profiles have the following configuration options:
-
Type:
string|object
-
Description: Path to a service module or the actual module itself (e.g.
require('path/to/service')
). -
Required:
Yes
-
Default:
none
- Type: `Array
-
Description: An array of strings containing the versions you intend to support. You cannot add anything you want here, only valid versions supported in core will be used. See
exports.VERSIONS
in the constants file. -
Required:
Yes
-
Default:
none
-
Type:
object
-
Description: Set profile specific cors options. These will override the default
corsOptions
set in the server config. Please see https://github.com/expressjs/cors#configuration-options for details. Themethods
configuration will not be honored if specified here. This is controlled by@asymmetrik/node-fhir-server-core
and cannot be overridden. -
Required:
No
-
Default:
none
Each profile has a predefined set of methods it can implement. If you do not want to support a particular interaction, for example, delete, then just don't implement the remove method. Each method you implement must return a promise and will receive the following three arguments:
-
args
- An object containing all the sanitized arguments passed into the request. The arguments these contain will change based on the endpoint, e.g. create and delete have different args and search has different args between a patient and an observation. See below for more information. -
logger
- A Winston logger instance used bynode-fhir-server-core
. -
context
- An object containing some information that may be useful when you are performing queries.
- Required: Yes
- Description: Return the number of resources of this type in your data store.
-
Return:
Promise.<number, Error>
-
Routes: No specific route, this is required to support count in the capability statement under
[version]/metadata
. - Example:
module.exports.count = (args, logger) => new Promise((resolve, reject) => {
logger.info(`Version >>> ${args.version}`);
db.patients.count((err, count) => {
if (err) {
logger.error('Error with Patient.count');
return reject(err);
}
return resolve(count);
});
});
- Required: No
- Description: Get the resource given one of several valid argument(s) and/or combination(s) of arguments in the req.query.
-
Return:
Promise.<object, Error>
-
Routes: Enables
/:version/[profile_name]
via GET and/[version]/[profile_name]/_search
via POST -
RouteArguments: Can receive a
version
and any other profile specific arguments. - Example:
module.exports.search = (args, logger) => new Promise((resolve, reject) => {
let query = buildQuery(req.query);
db.patients.find(query, (err, patients) => {
if (err) {
logger.error('Error with Patient.search');
return reject(err);
}
return resolve(patients);
});
});
- Required: No
- Description: Get the patient given an id in the req.params.
-
Return:
Promise.<object, Error>
-
Routes: Enables
:version/[profile_name]/:id
via GET -
RouteArguments: Can receive a
version
,id
, and any other profile specific arguments. - Example:
// In patient service
module.exports.searchById = (args, logger) => new Promise((resolve, reject) => {
db.patients.find({ _id: args.id }, (err, patient) => {
if (err) {
logger.error('Error with Patient.searchById');
return reject(err);
}
return resolve(patient);
});
});
- Required: No
- Description: Create a FHIR resource.
-
Return:
Promise.<{ id: string, version: string }, Error>
-
Routes: Enables
/:version/[profile_name]
via POST -
RouteArguments: Can receive a
version
,id
, and aresource
. - Example:
module.exports.create = (args, logger) => new Promise((resolve, reject) => {
let { id, resource } = args;
// This is a mongo specific thing
resource._id = id;
db.patients.insert(resource, (err, response) => {
if (err) {
logger.error('Error with Patient.create');
return reject(err);
}
return resolve({
id: response._id,
// This is optional if you support versions
version: 1
});
});
});
- Required: No
- Description: Create or update a FHIR resource.
-
Return:
Promise.<{ id: string, version: string }, Error>
-
Routes: Enables
/:version/[profile_name]/:id
via PUT -
RouteArguments: Can receive a
version
,id
, and aresource
. - Example:
module.exports.update = (args, logger) => new Promise((resolve, reject) => {
let { id, resource } = args;
// This is a mongo specific thing
resource._id = id;
db.patients.update(resource, (err, response) => {
if (err) {
logger.error('Error with Patient.update');
return reject(err);
}
return resolve({
id: response._id,
// This is optional if you support versions
version: 1
});
});
});
- Required: No
- Description: Delete a FHIR resource.
-
Return:
Promise.<object, { code: string, message: string}>
-
Routes: Enables
/:version/[profile_name]/:id
via DELETE -
RouteArguments: Can receive a
version
and anid
. - Example:
module.exports.remove = (args, logger) => new Promise((resolve, reject) => {
let { id } = args;
db.patients.remove({ _id: id }, (err, response) => {
if (err) {
logger.error('Error with Patient.delete');
return reject({
// Must be 405 (Method Not Allowed) or 409 (Conflict)
// 405 if you do not want to allow the delete
// 409 if you can't delete because of referential
// integrity or some other reason
code: 409,
message: 'Patient referenced in Observations and cannot be deleted. Please delete observations first.'
});
}
return resolve();
});
});
Consult the table below to view any and all arguments supported by individual profiles. They all support this set of common arguments as well as the ones defined in the argument files below.