Skip to content

Profile

Robert edited this page Jun 15, 2018 · 13 revisions

Overview

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.

Getting Started with Profiles

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!'));

Profile Configuration

Supported Profiles

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:

service

  • Type: string|object
  • Description: Path to a service module or the actual module itself (e.g. require('path/to/service')).
  • Required: Yes
  • Default: none

versions

  • 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

corsOptions

  • 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. The methods 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

Profile(s) Interface

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 by node-fhir-server-core.
  • context - An object containing some information that may be useful when you are performing queries.

Available Methods

count

  • 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);
	});
});

search

  • 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);
	});
});

searchById

  • 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);
	});
});

create

  • 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 a resource.
  • 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
		});
	});
});

update

  • 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 a resource.
  • 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
		});
	});
});

remove

  • 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 an id.
  • 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();
	});
});

Profile(s) Arguments

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.

Profile Profile Arguments
AllergyIntolerance src/server/profiles/allergyintolerance/allergyintolerance.arguments.js
CarePlan src/server/profiles/careplan/careplan.arguments.js
CareTeam src/server/profiles/careteam/careteam.arguments.js
Condition src/server/profiles/condition/condition.arguments.js
Device src/server/profiles/device/device.arguments.js
DiagnosticReport src/server/profiles/diagnosticreport/diagnosticreport.arguments.js
Goal src/server/profiles/goal/goal.arguments.js
Immunization src/server/profiles/immunization/immunization.arguments.js
Location src/server/profiles/location/location.arguments.js
Medication src/server/profiles/medication/medication.arguments.js
MedicationRequest src/server/profiles/medicationrequest/medicationrequest.arguments.js
MedicationStatement src/server/profiles/medicationstatement/medicationstatement.arguments.js
Observation src/server/profiles/observation/observation.arguments.js
Organization src/server/profiles/organization/organization.arguments.js
Patient src/server/profiles/patient/patient.arguments.js
Practitioner src/server/profiles/practitioner/practitioner.arguments.js
Procedure src/server/profiles/procedure/procedure.arguments.js

Additional Resources

Profile Specifications

Clone this wiki locally