FHIR® implementation
Implementation guidance for developers - focusing on FHIR® specifics.
Purpose
This site is intended for use by software developers looking to build a conformant GP Connect API interface using the FHIR® standard, with a particular focus on FHIR specifics.
Notational conventions
The keywords 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'MAY', and 'OPTIONAL' on this site are to be interpreted as described in RFC 2119.
FHIR implementation guidance
The purpose of the implementation guide is to describe adaptations of the base FHIR specification specific for GP Connect First of Type (FoT) implementations. It therefore focuses mainly on any additional constraints and specialisations from the base specification that apply to GP Connect. The complete specification therefore comprises the base FHIR specification plus the constraints and specialisations described herein. Where there is a conflict between the base specification and this web page, this web page shall take precedence.
FHIR overview
As outlined on the official HL7® FHIR website:
FHIR (Fast Health Interoperability Resources) is designed to enable information exchange to support the provision of healthcare in a wide variety of settings. The specification builds on and adapts modern, widely used RESTful practices to enable the provision of integrated healthcare across a wide range of teams and organisations.
FHIR versions
STU3 is a pre-release version of FHIR standard and as such is expected to evolve and develop over time. NHS Digital expects FHIR clients and servers (developed as part of GP Connect) to be maintained and uplifted to newer versions of the FHIR® standard as they become available and are staged into the GP Connect programme.
When a new release of the FHIR standard has been published for use NHS Digital will carry out an impact assessment of all FHIR resources used by the GP Connect API project to determine the impact of transitioning to the new FHIR release. Following this assessment, the FHIR resource library will be updated to include resources using this new release. NHS Digital will work with consumers and providers throughout this transition phase and are expected to maintain both versions of the FHIR release until it has been agreed that the old version can be deprecated.
FHIR implementations
The Health Level Seven (HL7®) International standards body maintains a list of open source FHIR implementations on its Wiki. Currently five FHIR server implementations and a number of client libraries are available as open source software. These are written in a variety of popular programming languages, such as Java, C#.NET, JavaScript and Python.
FHIR in scope
To help API implementers deal with the FHIR learning curve, NHS Digital has worked to constrain the scope of the FHIR® standard that is expected to be implemented in the first tranche of development work as follows:
- Resource
- Domain resource
- Common API
- Patient profiled as gpconnect-patient-1.
- Practitioner profiled as gpconnect-practitioner-1.
- Organisation profiled as gpconnect-organization-1.
- Location profiled as gpconnect-location-1
- Care record API
- Please refer to the Resource data types section of this page.
- Bookings API
- Schedule profiled as gpconnect-schedule-1
- Slot profiled as gpconnect-slot-1
- Appointment profiled as gpconnect-appointment-1
- Common API
- Resource metadata
- Bundle
- Data types
- Primitive types
- All primitive types SHALL be supported.
- Complex types
- The following complex types SHALL be supported.
- It is expected that further complex types will be introduced as required to model structured data.
- Primitive types
- Interactions
- Search
- Search parameter types
- Search prefixes
- lt (less than)
- le (less or equal to)
- gt (great than)
- ge (greater or equal to)
- eq (equal to)
- Parameters for all resources
- Search result parameters
- Operations
FHIR out of scope
GP Connect provider systems are not expected to implement the following aspects of the FHIR® standard under the scope of the first tranche of development work:
- Operations
- Validate a resource
- Meta operations
- Generate a document
- Process message
- Find a functional list
- ConceptMap operations
- Closure table maintenance
- Fetch records
- Questionnaire operations
- Terminology operations
- Interactions
- Instance
- HISTORY
- VREAD
- Type level
- HISTORY
- Whole system
- BATCH TRANSACTION
- HISTORY
- SEARCH
- Conditional interactions
- CREATE
- UPDATE
- DELETE
- Instance
- Search
- Parameter types
- Number
- String
- Quantity
- Composite
- URL
- Parameters for all resources
- _language
- _lastUpdate
- _tag
- _profile
- _security
- _text
- _content
- _filter
- Search result parameters
- _count
- _summary
- _elements
- _contained
- _containedType
- Chained parameters
- Paging / Page count
- Parameter types
- Resource metadata
- lastUpdated
- security
- tag
FHIR system conformance
Provider systems SHALL provide read-only FHIR CapabilityStatement resources that identify all the profiles and operations that each FHIR server supports for each resource type.
A FHIR server’s capability statement SHALL be available using the following capabilities interactions:
GET [base]/metadata {?_format=[mime-type]}
Please note: The [base]
portion may vary based on the GP Connect capability.
Refer to:
- Get the FHIR capability statement (Foundations) for the capability statement describing the Foundations and Appointment Management capabilities
- Get the FHIR capability statement (Access Record Structured) for the capability statement describing the Access Record Structured capability
FHIR resource conformance
To help a consumer find the correct set of reports for a use-case, a provider of resources SHALL, for any profile declared in CapabilityStatement.profile, mark resources with profile assertions documenting the profile(s) they conform to. A provider of resources SHOULD also ensure that any resource instance that would reasonably be expected to conform to the declared profiles SHOULD be published in this form.
GP Connect FHIR API conformance
GP Connect comprises a number of RESTful API bundles. Each API bundle is intended to support sets of related use cases, for example the Appointment API bundle supports viewing, booking and cancelling GP appointments in a number of scenarios.
Individual API bundles may be provided independently of each other. GP Connect conformance may be claimed in relation to one or more API bundles. A provider claiming to provide an API bundle must be fully conformant (that is, implement all the resource profiles and interactions for the API bundle as specified in this document and all the general requirements described herein).
Incomplete data - expected behaviour
Where resource instance data available in clinical systems is either insufficient or corrupt and thus a resource cannot be constructed by a provider system which meets the associated FHIR profile, the following guidance describes expected behaviour:
Scenario: GET resource by logical ID
An HTTP 500 error should be returned with an OperationOutcome resource providing diagnostic details. This may include details of the resource in the location element.
Scenario: FHIR response bundles
When a response bundle contains multiple resources, one or more of which cannot be populated as available data does not enable the resource in question to be populated to validate the associated profile, the provider will behave as follows: The request as a whole will error with a 500 HTTP Status returned, together with the appropriate OperationOutcome resource providing diagnostic detail of the error.
FHIR resources
Resource data types
The FHIR specification defines a set of data types that are used for the resource elements.
The user locale (that is, user’s language, region and any special variant preferences that the user may want to see in their user interface) of a system SHALL NOT affect the FHIR on the wire representation of any data types (especially date-time and number formats).
Certain aspects of primitive data type representation warrant further consideration and SHALL be taken into consideration when designing and constructing FHIR resources.
For example:
- leading 0 digits are not allowed
- strings SHALL NOT exceed 1MB in size
- URIs are case sensitive
- UUID values (urn:uuid:53fefa32-fcbb-4ff8-8a92-55ee120877b7) use all lower case
- dates have no time zone
- dates can be partial dates (for example, just ‘year’ or ‘year + month’)
- precision of the decimal value has significance
- primitive types other than string SHALL NOT have leading or trailing whitespace
- use of null and empty / zero length values in XML and JSON representations
Resource narrative
The FHIR resource narrative is not currently expected to be populated.
Resource references
The FHIR resource model includes resource references from one resource to another.
A reference can be either:
- a relative or absolute URL to a resource managed by the same resource server (a local reference), or
- an absolute URL to a resource managed by another resource server (a remote reference)
A provider’s ability to process a request relating to a resource may depend on its ability to utilise one or more resource references that the resource contains (for example, its ability to ‘follow the links’ to other resources).
Resource metadata
Servers SHALL provide the profile
metadata for each resource, asserting that the content conforms to one of the GP Connect resource profiles.
Servers SHALL provide the version Id
metadata for each item. This SHALL change each time the content of the resource changes.
Consumer creating or amending a resource SHALL provide the profile
metadata details within the sent resource. The profile
metadata should be checked for by the provider to ensure predictable process and for forward compatibility when a server can handle multiple profiles for the same type of resource.
Clients SHALL use the version Id
when performing updates to allow management of resource contention and to protect against lost updates.
Resource transactions
When performing an update or creating resource transactions, servers:
- SHALL validate the content against valid profiles and business rules before creating/updating the resource
- MAY apply business rules that alter the content
- MAY merge updated content with existing content
Servers SHALL validate the existence of any referenced resources when creating or updating a resource. For example, a Slot
reference (for example, Slot/D497DB00-99AA-11E5-A837-0800200C9A66
) used when creating a new Appointment
would be checked for existence on the server and an error returned (and the create interaction aborted) if the slot does not exist.
Refer to the GitHub hosted GP Connect FHIR repository for the published FHIR profiles.
Refer to the HL7® FHIR® Validator page for the most up to date details on how FHIR resources can be validated.
Servers SHALL provide a read interaction for every resource it accepts update interactions on.
Consumers SHALL follow the pattern described in the Transactional Integrity section of the base FHIR specification, built on top of version-aware updates, for updating resources.
FHIR® resource interactions
Requests
Servers SHALL be able to consume and process the following requests for GP Connect FoT:
Interaction | Path | Request verb | Request content-type | Body | Prefer | Conditional |
---|---|---|---|---|---|---|
read |
/[type]/[id] |
GET |
N/A | N/A | N/A | ETag |
update |
/[type]/[id] |
PUT |
R | Resource | O | If-Match |
delete |
/[type]/[id] |
DELETE |
N/A | N/A | N/A | N/A |
create |
/[type] |
POST |
R | Resource | O | N/A |
search |
/[type]? |
GET |
N/A | N/A | N/A | N/A |
(operation) |
/[type]/$[name] /[type]/[id]/$[name] |
POST GET |
R application/x-www-form-urlencoded |
Parameters form data |
N/A | N/A |
N/A = not present, R = required, O = optional
Responses
Servers SHALL be expected to produce the following responses for GP Connect FoT:
Interaction | Response content-type | Body | Location | Content-location | Versioning | Status codes |
---|---|---|---|---|---|---|
read |
R | R: Resource | N/A | R | ETag |
200 , 404 , 410 |
update |
R | R: Resource | N/A | R | ETag |
200 , 201 , 400 , 404 405 , 409 , 412 , 422 |
delete |
R | R: Operation Outcome | N/A | N/A | N/A | 200 , 204 , 404 , 405 , 409 , 412 |
create |
R | R: Resource | R | R | ETag |
201 , 400 , 404 405 , 422 |
search |
R | R: Bundle | N/A | N/A | N/A | 200 , 403 |
(operation) |
R | R: Parameters/Resource | N/A | N/A | N/A | 200 , 400 , 403 , 404 , 422 |
N/A = not present, R = required, O = optional
Response codes
Servers SHALL produce the following main HTTP status codes:
HTTP status code | Description |
---|---|
200 |
OK |
201 |
Created |
400 |
Bad request |
401 |
Unauthorized |
403 |
Forbidden |
404 |
Not found |
405 |
Method not allowed |
409 |
Conflict |
410 |
Gone |
412 |
Precondition failed |
415 |
Unsupported media type |
422 |
Unprocessable entity |
500 |
Internal server error |
501 |
Not implemented |
Rejecting updates
OperationOutcome may be returned with any HTTP 4xx
or 5xx
response, but is not required - many of these errors may be generated by generic server frameworks underlying a FHIR server.
Servers are permitted to reject update interactions because of integrity concerns or other business rules, and return HTTP status codes accordingly (usually a 422
).
As outlined in the FHIR specification, any of these errors SHOULD be accompanied by an OperationOutcome resource that provides additional detail concerning the issue.
Refer to FHIR Guidance - Error Handling for full details of error codes that SHALL be used when returning an operation outcome error.
Compartment based access
VERB [base]/[compartment_type]/[id]/[type]{?_format=[mime-type]}
Each resource type may belong to one or more logical compartment. A compartment is a logical grouping of resources which share a common property.
Servers SHALL support the Patient
compartment for Appointment
access.
The patient compartment includes any resources where the subject
of the resource is the patient.
For example, to retrieve a list of all a patient’s appointments, use the URL:
GET [base]/Patient/[id]/Appointment
Servers SHALL support searching within this compartment by start
and end
date/time, for example:
GET [base]/Patient/[id]/Appointment?start=[{search_prefix}start_date]{&start=[{search_prefix}end_date]}
Read resource
A resource read takes the following format:
GET [base]/[type]/[id]{?_format=[mime-type]}
The returned resource SHALL have an id
element with a value that is the [id].
Servers SHALL return an ETag
header with the version Id
of the resource.
Available for resources
Capability | Resource(s) |
---|---|
Foundations | Patient , Practitioner , Organization |
Access Record | TBC |
Appointments | Appointment , Schedule , Slot , Location |
Important: In workshop discussions with all principal GP system vendors it has been agreed that record locking (inside the GP system) will not impact on the ability of clients to query the GP Connect APIs and to obtain the latest saved/committed clinical and administrative data.
Retrieving a patient resource by logical ID
Request
GET [base]/Patient/[id]
For example:
GET [base]/Patient/1A6E1B1C-6340-4663-926C-9CD1306EAAF8?_format=application/xml+fhir
Tip: In this example the response format has been specified in the request URL using the _format
parameter. This could also have been specified using the HTTP Accept header mechanism.
Response
<Patient xmlns="http://hl7.org/fhir"> <id value="1A6E1B1C-6340-4663-926C-9CD1306EAAF8" /> <meta> <profile value="http://fhir.nhs.net/StructureDefinition/gpconnect-patient-1" /> </meta> <identifier> <system value="http://fhir.nhs.net/Id/nhs-number" /> <value value="9900002831" /> </identifier> <identifier> <type> <coding> <system value="http://fhir.nhs.net/ValueSet/gpconnect-patient-identifier-type-1" /> <code value="Local" /> <display value="Local identifier" /> </coding> </type> <system value="http://fhir.nhs.net/Id/local-identifier" /> <value value="L12345" /> </identifier> <name> <use value="usual" /> <family value="Taylor" /> <given value="Sally" /> <prefix value="Mrs" /> </name> <birthDate value="1947-06-09" /> <address> <use value="home" /> <type value="both" /> <line value="42, Grove Street" /> <city value="Overtown" /> <district value="West Yorkshire" /> <postalCode value="LS21 1PF" /> </address> </Patient>
Create resource
To create a new resource a RESTful POST operation with a request body SHALL be used.
POST [base]/[resourcetype]
When the server creates a new resource and returns a 201
Created HTTP status code, it SHALL also return a Location
header which contains the new logical Id
and version Id
of the created resource.
Location: [base]/[type]/[id]/_history/[vid]
[id] and [vid] are the newly created logical Id
and version Id
for the resource version. An ETag
header with the version Id
and a Last-Modified
header will also be included in the response.
Available for resources
Capability | Resource(s) |
---|---|
Foundations | |
Access Record | |
Appointments | Appointment |
Create example: Book an appointment for a patient
Refer to Book an appointment for request and response body examples for a create request.
Update resource
To update an existing resource, a RESTful PUT operation with a request body SHALL be used.
PUT [base]/[resourcetype]/[id]
The PUT operation will only be used to update existing resources. If the specified resource within the URL does not exist on the provider system an error SHALL be returned.
Capability | Resource(s) | Field(s) |
---|---|---|
Foundations | ||
Access Record | ||
Appointments | Appointment |
reason, description, comment |
Update example: Modify the appointment booking reason
Refer to Amend an appointment for request and response body examples for a request which updates a resource using the PUT HTTP verb.
Delete resource
To delete an existing resource, a RESTful DELETE operation with no request body SHALL be used.
DELETE [base]/[resourcetype]/[id]
Capability | Resource(s) |
---|---|
Foundations | |
Access Record | |
Appointments |
Operations
Operations are used (a) where the server needs to play an active role in formulating the content of the response, not merely return existing information, or (b) where the intended purpose is to cause side effects such as the modification of existing resources, or creation of new resources.
As outlined in the Extend and Restricting the API section of the FHIR® standard, NHS Digital has decided to prefix its operation names with a short prefix (for example, gpc
) followed by a ‘.’ to reduce the likelihood of name conflicts.
Search resources
A simple search is executed by performing a GET
request optionally accompanied by zero or more name-value URL encoded parameters:
GET [base]/[resourcetype]?name=value&...
In order to enable searching by date/time range, servers SHALL support the following prefixes as defined in the base FHIR specification for date parameters: eq, gt, lt, ge, le.
To search for all the appointments for a patient that occurred over a 2-year period:
GET [base]/Patient/1A6E1B1C-6340-4663-926C-9CD1306EAAF8/Appointment?start=ge2014-01-01&start=le2015-12-31
Chained parameters
Servers SHALL support searching by a chained Patient
identifier parameter for references to Patient
resources that conform to the GP-Patient
profile (and therefore have an NHS number identifier). For example:
GET [base]/AllergyIntolerance?patient.identifier=http://fhir.nhs.net/Id/nhs-number|1234569876
Search example: Search for a patient resource by business ID
Request
GET [base]/Patient?identifier=http://fhir.nhs.net/Id/nhs-number|9900002831
If a patient resource for NHS number 9900002831 exists then the server SHALL return a bundle containing all patient resources with the specified NHS number identifier.
Response
<Bundle>
<Patient xmlns="http://hl7.org/fhir">
<id value="1A6E1B1C-6340-4663-926C-9CD1306EAAF8" />
<meta>
<profile value="http://fhir.nhs.net/StructureDefinition/gpconnect-patient-1" />
</meta>
<identifier>
<system value="http://fhir.nhs.net/Id/nhs-number" />
<value value="9900002831" />
</identifier>
<name>
<use value="usual" />
<family value="Smith" />
<given value="Mike" />
<prefix value="Mr" />
</name>
<birthDate value="1977-01-09" />
<address>
<use value="home" />
<type value="both" />
<line value="2, The Green" />
<city value="Harrogate" />
<district value="Yorkshire" />
<postalCode value="HG1 4AF" />
</address>
</Patient>
</Bundle>
Advanced search
Servers SHALL implement the _query search parameter to enable custom-named search profiles to be defined and used which describe a specific query operation.
GET [base]/[resourcetype]?_query=[query_name]&name=value&...
Servers SHOULD implement the standard search equivalent of the advanced custom-named search for queries defined under the GP Connect FoT.
Request
GET [base]/Schedule?_query=getschedule&date=ge2016-05-12&date=le2016-05-26
Response
<Bundle xmlns="http://hl7.org/fhir">
<type value="searchset"/>
</Bundle>