Page Status: updated 2023-06-21

FHIR and REST

Page index

General considerations

FHIR® resources are exchanged using the RESTful paradigm in the Swedish National Medication List. Each "resource type" has a selection of the same set of interactions defined that can be used to manage the resources in a highly granular fashion. Transactions are performed on the server resource using an HTTP request/response with required access token.

Recommended reading, in complement with this implementation guide, is the FHIR RESTful API.

FHIR Version

Supported version is FHIR R4. Supported FHIR resources and their profiles can be found under the Resources section

Resource formats

By default FHIR has support for exchanging data both in JSON and XML format. However all validation of the Swedish National Medication List has been done using JSON why this is the recommended format for exchanging data. See HL7 FHIR Resource format

Profiles and validation of input

Validation of submitted resources (using POST or PUT) is never done based on the profile information provided in Meta.profile. In those cases where there are several profiles available for a certain resource, for example NLLMedicationDispense and NLLDispensePaperPrescription, the data provided in the resource is used to determine the kind of resource instance.

Notation

Throughout this guide the following notation is used to specify how to interact with the Swedish National Medication List using HTTP calls to the server. It follows the same principles as the notation used by HL7 Style Guide with a few extensions.

VERB [base]/[resource]/[id]{?(name_1=[value]|&name_2=[value]){&name_3=[value]}}

  • VERB The HTTP method, i.e. GET, POST, PUT.
  • [xyz] Mandatory parameters are surrounded by square brackets.
  • {xyz} Optional content is surrounded by curly brackets.
  • (A|B)C Parentheses are used for grouping data and vertical bar as a mathematical or, in this case the meaning is "A" or "B" followed by "C".

General parameter types:

  • [base] The Service Base URL, i.e. http{s}://[domain]{/[path]}.
  • [resource] Type of resource, e.g. Patient, MedicationRequest e.t.c..
  • [id] Logical ID of an instance of a resource.
  • [vid] Version ID of an instance of a resource.
  • [compartment] Type of resource as a compartment.
  • [parameters] Placeholder for all parameters as defined for the specific interaction.

Basepath

All examples in this implementation guide refers to a [base] in the start of an URI / URL. Base is an abbreviation of Service Base URL and takes the form https://[sub_domain].[main_domän]/[api-name]/[api-version]/[application].

For the Swedish National Medication List this would be
https://<sub-domain>.ehalsomyndigheten.se/<api-name>/v1/fhir or
https://<sub-domain>.ehalsomyndigheten.sjunet.org/<api-name>/v1/fhir.

See Test- och produktionsmiljöer hos E-hälsomyndigheten for more information.

A typical example in the guide would then look like this GET [base]/Patient?_id=123.

For more information about the basepath see HL7 Service Base URL.

URIs vs URLs and encoding of URLs

FHIR use URIs (Uniform Resource Identifier) and URLs (Uniform Resource Locator) frequently as a way to identify things and point at where things can be found. For example a code in a value set is bound to the code system where the code is defined. The code system is identified by an URI, e.g. "http://unitsofmeasure.org". An other example are FHIR profiles and extensions who has a canonical identifier in the form of an URI, e.g. "http://electronichealth.se/fhir/StructureDefinition/NLLMedicationRequest".

An URL is an URI that acts as an address to something. In the latter example above the element is named url to reflect the idea that the specification should be available on the same address as it's identification. NB! This is not the case yet for profiles, extensions and value sets created by the National Medication List.

The look of an URI and the different parts in one is quite familiar to most but there are some constraints that may be less known. An URI is based on US-ASCII and characters like :/?= has a special meaning. It is important to encode an URI correctly to avoid technical issues. An example is when performing a search when the URL may be something like GET [base]/Patient?identifier=http://electronichealth.se/identifier/personnummer|196411193086. This may or may not work in a practical scenario but to avoid issues the URL should be percent-encoded like this GET [base]/Patient?identifier=http%3A%2F%2Felectronichealth.se%2Fidentifier%2Fpersonnummer%7C196411193086.

More information about URIs and URLs can be found at http://hl7.org/fhir/R4/http.html#general, http://hl7.org/fhir/R4/datatypes.html and https://www.rfc-editor.org/rfc/rfc3986.

UUID

UUIDs generated by the Swedish National Medication List follows RFC 4122 type 4 and the FHIR 4 specification, with a few exceptions when type 3 is used. RFC 4122 allows UUIDs to be in both upper and lower case but FHIR states that UUID IDs shall be in lower case. UUIDs in the Swedish National Medication List are therefore allways in lower case and all UUIDs sent to the Medication List should be in lower case.

CRUD operations

Parameters and extended operations

Resource specific request parameters and extended operations are described per resource in the section Resources.

In addition to the resource specific parameters the following generic parameters are supported.

Parameter Description
_format This parameter is optional and can be used to set the prefered format of the returned data. Two options are available JSON and XML. Default is JSON if no format is requested.

Note: All tests performed by the Swedish eHealth Agency to verify the accuracy of the Swedish National Medication List has been done using JSON. The XML option is part of the FHIR spec, but the Swedish eHealth Agency should be contacted before it is used.

Create

A create interaction is performed using an HTTP POST with the resource in the body of the request.

POST [base]/[type]

The server will accept the resource in the HTTP body and create a new instance of the resource with version id 1, as long as the content meets the validation and business rules of the application. If the body contains an id element, it will be ignored. The server will always assign a new logical id.

Many fields are auto generated by the Swedish National Medication List. Such fields are usually ignored if they contain data when the resource is uploaded. Detailed documentation about business rules and logic can be found in Handbok för vård och apoteksaktörer - Nationella läkemedelslistan.

If the resource was sucessfully created the server returns HTTP status 201 and a Location header which contains the new Logical Id and Version Id of the created resource. If there was an error creating the resource, due to faulty body content e.g. not compliant to the resource profile, HTTP status >=400 is returned.

Create is not supported for all resources. See the section for each resource to see supported actions.

Read

A read interaction accesses the current contents of one or several resource(s). The interaction is performed by an HTTP GET command, for example

  • GET [base]/[type]/[id]
  • GET [base]/fhir/Patient/54ff7817-4e4e-4215-9b90-b29a8c0c3143

The id referred to above is the logical id of the resource instance. It is possible to fetch all stand-alone resource types by logical id. Resources which are available as contained resources (e.g. Practitioner) cannot be fetched by their logical id.

The interaction must always include the required security access token, as described in the security chapter. The operation will return one single resource with the provided identifier, if it exists, otherwise a HTTP status 404, 410 or similar is returned if the resource doesn't exist or is inaccessible.

Update

An update interaction is performed using an HTTP PUT with the resource in the body of the request. The body resource must have an id element that has an identical value to the id in the URL.

PUT [base]/[type]/[id]

The server will accept the resource in the HTTP body, as long as the content meets the validation and business rules of the application and creates a new version of the resource instance and increment the version id by 1. Update action is not supported for all resources. See the section for each resource to see supported actions.

A PUT replaces the resource in its entirety making it possible to perform a GET on a resorce, followed by some changes and finally a PUT of the changed resource. Partial updates of resources using the PATCH method is not supported.

Many fields are auto generated by the Swedish National Medication List. Such fields are usually ignored if they contain data when the resource is uploaded. Detailed documentation about business rules and logic can be found in Handbok för vård och apoteksaktörer - Nationella läkemedelslistan.

If the resource was sucessfully updated the server returns HTTP status 200 and a Location header which contains the Logical Id and Version Id of the updated resource. If there was an error updating the resource, due to faulty body content e.g. not compliant to the resource profile, HTTP status >=400 is returned.

Delete

NLL does not support delete actions initiated from an external client. Instead the resource which is no longer valid or faulty should be updated with a status that reflects this. The supported status values are defined on each resource, e.g. "entered-in-error", "inactive" or similar. The application logic of the Swedish National Medication List will at different timeframes clear these type of faulty or outdated records.

A search for information is typically performed by the HTTP GET method followed by the domain adress, the resource and optional parameters. A search is defined by using a question mark in the url.

A succesful search returns HTTP status 200 OK and a Bundle with type = searchset containing the result of the search as a collection of one or more resources.

GET [base]/[type]{?[param=value]{&[param=value]...}}

Each parameter is entered after the question mark as a series of name=value pairs separated by an ampersand.

Examples:

  • To search for a patient with the logical ID 123.
    GET http://acme.org/fhir/Patient?_id=123

  • To search for all medication requests of the patient with logical ID 123, where the medication request's status is active or cancelled.
    GET http://acme.org/fhir/MedicationRequest?patient._id=123&status=active,cancelled

When the logical id is known, as in the first example above, a 'read' can be performed instead.

GET [base]/[type]/[logical id]

Example:

  • GET http://acme.org/fhir/Patient/123

Another form of search is the compartment search, where one resource is specified with it's logical ID followed by a second resource. All instances of the second resource with a relationship to the first resource will then be returned.

GET [base]/[type_1]/[logical_id]/[type_2]

Example:

  • To get all provenances which are related to the medication request with the logical ID 123.
    GET http://acme.org/fhir/MedicationRequest/123/Provenance

Note: It is currently not possible to perform compartment searches with parameters.

There are many search parameters and search result parameters described in the FHIR specification, both in general and per resource. The supported subset of those parameters are specified per resource in this implementation guide. It is for example not possible to specify the sort order by the _sort parameter.

For more information about searching in FHIR see HL7 FHIR Search and HL7 FHIR HTTP Search. See also URI and URL for information about encoding of search URLs.

Prefix in search queries

For ordered parameter types (number, date, and quantity), a prefix to the parameter value may be used to control the nature of the matching. Equal is defaulted if no prefix is present.

Prefix Supported for type Comment
gt - Greater than
lt - Less than
ge date, dateTime Greater than or equal
le date, dateTime Less than or equal
eq date, dateTime, number Equals

Example:
GET [base]/fhir/MedicationRequest?identifier=199811162396&status=active&authoredon=ge2018-03-14

Notes on personal identification information as query parameters. Since connection is achieved through https and mutual TLS, the connection is first settled and the rest of the URL is sent as part of the corresponding HTTP request which occurs within the encrypted tunnel, hence invisible to third parties.

Outcome

Managing returned content

It is possible to specify the preferred information to be returned on a successful create or update (POST and PUT) request. The preference is specified in the header parameter Prefer. This only applies when working with standard operations. Extended operations does not support the return header.

Prefer: return=minimal
Prefer: return=representation
Prefer: return=OperationOutcome

A minimal request will return an empty body. A representation request will return the created or updated resource. An operation outcome request will return an OperationsOutcome resource (see below) with information about the operation. The default behavior is minimal if no preference is specified. There is one execption, as "minimal" is not allowed for MedicationRequest. One of "representation" or "OperationOutcome" must be specified when creating or updating a MedicationRequest.

NB! There is a special case using the Prefer header for a Medication resource. The implementation of the attribute Medication.amount contains an error as it is treated as an array and not as a single object. As the correction is not backwards compatible the work around available is a possibility to request a Medication on the correct format using Prefer: nllOption=CompliantMedication. The default behaviour (when no header is provided) is still a Medication where Medication.amount is treated as an array. This is planned to be corrected in the next major release.

OperationOutcome

An OperationOutcome can be returned on a successfull create or update request (see above) describing the result of the action (HTTP Status 2*). An OperationOutcome will also always be returned on unsuccessful requests (responses related to HTTP Status 4* or 5*).

Name Description
severity Used statuses: error, warning, information
code The issue type. Commonly "business-rule" for fault or warning related to business logic validation. "invalid" if posted resource doesn't comply with the resource profile.
details Details further explaning the fault
details.coding.system URI to the used code system (e.g. the AFF suite)
details.coding.code The originating fault code, e.g. AFF-code
details.coding.display The display value of the fault, normally in Swedish
details.text Not always populated, then see display for description of each fault

Sequence diagrams with HTTP response coded

The sequence diagrams below shows HTTP response codes for the typical scenarios when accessing the Swedish National Medication List.

legend_seq_diagram

generic_operations_seq_diagram