This page is part of the FHIR Specification (v1.8.0: STU 3 Draft). The current version which supercedes this version is 5.0.0. For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4 R3 R2
FHIR Infrastructure Work Group | Maturity Level: N/A | Ballot Status: STU 3 |
Each "resource type" has the same set of interactions defined that can be used to manage the resources in a highly granular fashion. Applications claiming conformance to this framework claim to be conformant to "RESTful FHIR" (see Conformance).
Note that in this RESTful framework, transactions are performed directly on the server resource using an HTTP request/response. The API does not directly address authentication, authorization, and audit collection - for further information, see the Security Page.
The API describes the FHIR resources as a set of operations (known as "interactions") on resources where individual resource instances are managed in collections by their type. Servers can choose which of these interactions are made available and which resource types they support. Servers SHALL provide a Capability Statement that specifies which interactions and resources are supported.
The following logical interactions are defined:
Instance Level Interactions | |
read | Read the current state of the resource |
vread | Read the state of a specific version of the resource |
update | Update an existing resource by its id (or create it if it is new) |
patch | Update an existing resource by posting a set of changes to it |
delete | Delete a resource |
history | Retrieve the change history for a particular resource |
Type Level Interactions | |
create | Create a new resource with a server assigned id |
search | Search the resource type based on some filter criteria |
history | Retrieve the change history for a particular resource type |
Whole System Interactions | |
capabilities | Get a capability statement for the system |
batch/transaction | Update, create or delete a set of resources in a single interaction |
history | Retrieve the change history for all resources |
search | Search across all resource types based on some filter criteria |
In addition to these interactions, there is an operations framework, which includes endpoints for validation, messaging and Documents.
Style Guide
The interactions on this page are defined like this:
VERB [base]/[type]/[id] {?_format=[mime-type]}
base
: The Service Base URLmime-type
: The Mime Typetype
: The name of a resource type (e.g. "Patient")id
: The Logical Id of a resourcevid
: The Version Id of a resourcecompartment
: The name of a compartmentparameters
: URL parameters as defined for the particular interaction{}
is optionalImplementations constructing URLs using these patterns SHOULD conform to RFC 3986 Section 6 Appendix A which requires percent-encoding for a number of characters that occasionally appear in the URLs (mainly in search parameters).
This specification uses the underscore as a prefix to disambiguate reserved names from other names in 3 cases:
In addition, the character $
is used as a prefix to operation names that are RPC-like additions to the base
API defined, either by this specification or by implementers.
The Service Base URL is the address where all of the resources defined by this interface are found. The Service Base URL takes the form of
http(s)://server{/path}
The path portion is optional, and does not include a trailing slash. Each
resource type defined in this specification has a manager (or "entity set")
that lives at the address /[type]
where the
[type]
is the name of the resource type.
For instance, the resource manager for the type
Patient
will live at:
https://server/path/Patient
All the logical interactions are defined relative to the service root URL. This means that if the address of any one FHIR resource on a system is known, the address of other resources may be determined.
Note: All URLs (and ids that form part of the URL) defined by this specification are case sensitive. Clients SHOULD encode URLs using UTF-8, and servers SHOULD decode them assuming they are UTF-8 (for background, see here ).
Note that a server may use a path of the form http://server/...[xx]...
where the [xx]
is some variable
portion that identifies a particular instantiation of the FHIR API. Typically, the variable id
identifies a patient or a user, and the underlying information is completely compartmented
by the logical identity associated with [xx]
. In this case, the FHIR API presents a
patient or user centric view of a record, where authentication/authorization is
explicitly granted to the URL, on the grounds that some identifiable user is associated
with the logical identity. It is not necessary to explicitly embed the patient id in the
URL - implementations can associate an FHIR end-point with a particular patient or
provider by using an OAuth login. See Compartments for the logical underpinning.
Identity
Systems often need to compare two URLs to determine whether they refer to the same underlying object or not. For the purposes of this specification, the following rules apply:
?
) is ignoredhttp:
and https:
SHALL NOT be used to refer to different underlying objects
For example:
http://myserver.com/Patient/1
and https://myserver.com/Patient/1
refer to the same underlying object, while http://myserver.com:81/Patient/1
is a distinct entity from either of the above.
This does not mean that the two addresses need to be treated the same, or that a server must serve both addresses, or that the content from the two addresses must be identical, but just that if these two
addresses have the same identity, and if both are served, they must both represent the same underlying object. Systems are not required to
check that this is true. Note: the identity comparison for protocols other than http:/https: is undefined.
Each resource has an associated set of resource metadata elements. These map to the HTTP request and response using the following fields:
Metadata Item | Where found in HTTP |
---|---|
Logical Id (.id) | The Id is represented explicitly in the URL |
Version Id (.meta.versionId) | The Version Id is represented in the ETag header |
Last modified (.meta.lastUpdated) | HTTP Last-Modified header |
Note that the Version Id is considered a "weak" ETag and ETag
headers
should be prefixed with W/
and enclosed in quotes, for example:
ETag: W/"3141"
Using HTTPS is optional, but all production exchange of healthcare data SHOULD use SSL and additional security as appropriate. See HTTP Security for further information. Most operations will require user authentication, and all operations that do are subject to RBAC and/or ABAC , and some operations may depend on appropriate consent being granted.
See the HTTP Security guidance on how to handle access denial response.
Note: to support browser-based client applications, recommend that servers SHOULD implement cross-origin resource sharing for the interactions documented here. Experience shows that this is an area where ongoing issues may be expected as security holes are found and closed in an ongoing basis.
This specification makes rules about the use of specific HTTP status codes in particular circumstances where the status codes SHALL map to particular states correctly, and only where the correct status code is not obvious. Other HTTP status codes may be used for other states as appropriate, and this particularly includes various authentication related status codes and redirects. Authentication redirects should not be interpreted to change the location of the resource itself (a common web programming error).
FHIR defines an OperationOutcome resource that can be used to convey specific detailed
processable error information. For a few combinations of interactions and specific
return codes, an OperationOutcome is required to be returned as the content of the response.
The 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.
In the interests of managing band-width, this specification allows clients to specify what kind of content to return.
Clients may use the If-Modified-Since
, or If-None-Match
HTTP header on a read
request.
If so, they MUST accept either a 304
Not Modified as a valid status code on the response (which means that the
content is unchanged since that date) or full content (either the content has changed,
or the server does not support conditional request).
Servers can return 304
Not Modified where content is unchanged since the
If-Modified-Since
date-time or the If-None-Match
ETag specified or they can
return the full content as normal. This optimisation is relevant in reducing bandwidth for caching purposes and servers are encouraged but
not required to support this. If servers don't support conditional read, they just return the full content.
These interactions are performed using POST
, PUT
or PATCH
, and
it may be appropriate for a server to return either only a status
code, or also return the entire resource that is the outcome of the
create or update (which may be different to that provided by the
client). In the case of transactions this means returning a Bundle with just the Bundle.entry.response
populated for each entry,
and not the Bundle.entry.resource
values.
The client can indicate whether the entire resource is returned using the HTTP return preference :
Prefer: return=minimal Prefer: return=representation Prefer: return=OperationOutcome
The first of these two asks to return no body. The second asks to return the full resource. The third asks the server to return an OperationOutcome resource containing hints and warnings about the operation rather than the full resource. Servers SHOULD honor this header. In the absence of the header, servers may choose whether to return the full resource or not (but not the OperationOutcome; that should only be returned if explicitly requested). Note that this setting only applies to successful interactions. In case of failure, servers SHOULD always return a body that contains an OperationOutcome resource.
The formal MIME-type for FHIR resources is application/fhir+xml
or application/fhir+json
.
The correct mime type SHALL be used by clients and servers:
application/fhir+xml
application/fhir+json
text/turtle
(only the Turtle format is supported)Servers SHALL support server-driven content negotiation as described in section 12 of the HTTP specification.
Note: between FHIR DSTU2 and STU3, the correct mime type was changed from application/xml+fhir and application/json+fhir to application/fhir+xml and application/fhir+json. Servers MAY also support the older mime types, and are encouraged to do so to smooth the transtion process.
In order to support various implementation limitations, servers SHOULD support the optional _format
parameter to
specify alternative response formats by their MIME-types. This parameter allows a client to override the accept
header value when it is unable to set it correctly due to internal limitations (e.g. XSLT usage). For the _format
parameter, the values xml
, text/xml
, application/xml
, and application/fhir+xml
SHALL be interpreted to mean the XML format, the codes json
, application/json
and
application/fhir+json
SHALL be interpreted to mean the JSON format, and the codes ttl
and text/turtle
SHALL be interpreted to mean the Turtle RDF format. In addition, the values
html
and text/html
are allowed.
FHIR uses UTF-8 for all request and response bodies. Since the HTTP specification (section 3.7.1)
defines a default character encoding of ISO-8859-1, requests and responses SHALL explicitly set
the character encoding to UTF-8 using the charset
parameter of the MIME-type in the Content-Type
header.
Requests MAY also specify this charset
parameter in the Accept
header and/or use the Accept-Charset
header.
Note: the _format
parameter does not override the content-type
header.
The content types application/x-www-form-urlencoded
is also accepted for posting search
requests.
If neither the accept header nor the _format parameter are specified, the MIME-type of the content returned by the server is undefined and may vary.
Implementation Note: If a client provides a generic mime type in the Accept header (application/xml, text/json, or application/json), the server SHOULD respond with the requested mime type, using the XML or JSON formats described in this specification as the best representation for the named mime type (though see the note on the Binary resource).
Servers that support this API SHOULD provide full version support - that is, populate and track
versionId
correctly, support vread
, and implement version aware updates.
Supporting versions like this allows for related systems to track the correct version of information,
and to keep integrity in clinical records. However, many current operational systems do not
do this, and cannot easily be re-engineered to do so.
For this reason, servers are allowed to not provide versioning support and this API does not enforce that versioning is supported. Clients may elect to only interact with servers that do provide full versioning support. Systems declare their support for versioning in their Capability Statements. Where they can indicate one of three levels for versioning support:
Server should always return the default timezone for date searches in the HTTP Response headers using the Date header. Note: Servers are not required to have a default timezone.
The read
interaction accesses the current contents of a resource. The interaction
is performed by an HTTP GET
command as shown:
GET [base]/[type]/[id] {?_format=[mime-type]}
This returns a single instance with the content specified for the resource type.
This url may be accessed by a browser. The possible values for the
Logical Id ("id") itself are described in the id type.
The returned resource SHALL have an id
element with a value that is the [id].
Servers SHOULD return an ETag
header with the versionId of the resource (if versioning is supported) and a Last-Modified
header.
Note: Unknown resources and deleted resources are treated differently on a read: A GET
for a deleted
resource returns a 410
status code, whereas a GET
for an unknown resource returns 404
. Systems that do
not track deleted records will treat deleted records as an unknown resource. Since deleted resources may be brought
back to life, servers MAY include an ETag on the error response when reading a deleted record to allow version
contention management when a resource is brought back to life.
In addition, the search parameter _summary
can be used when reading a resource:
GET [base]/[type]/[id] {?_summary=text}
This requests that only a subset of the resource content be returned,
as specified in the _summary
parameter, which can have the values
true
, false
, text
& data
.
Note that a resource that only contains a subset of the data is
not suitable for use as a base to update the resource, and may not
be suitable for other uses. The same applies to the _elements parameter - both
that it should be supported, and the subset implications. Servers SHOULD use
the SUBSETTED Security Label
to explicitly mark such resources.
The vread
interaction preforms a version specific read of the resource. The interaction
is performed by an HTTP GET
command as shown:
GET [base]/[type]/[id]/_history/[vid] {?_format=[mime-type]}
This returns a single instance with the content specified for the resource type for that
version of the resource.
The returned resource SHALL have an id
element with a value that is the [id]
, and a meta.versionId
element with a value of [vid]
. Servers SHOULD return an ETag
header with the versionId (if versioning is supported)
and a Last-Modified
header.
The Version Id ("vid") is an opaque identifier that conforms to the same format requirements as
a Logical Id. The id may have been found by performing a history interaction (see below), by recording the
version id from a content location returned from a read
or from a version specific reference in a
content model. If the version referred to is actually one where the resource was deleted, the
server should return a 410
status code.
Servers are encouraged to support a version specific retrieval of the current version of the
resource even if they do not provide access to previous versions. If a request
is made for a previous version of a resource, and the server does not support accessing
previous versions (either generally, or for this particular resource), it should
return a 404
Not Found error, with an operation outcome explaining that
history is not supported for the underlying resource type or instance.
The update
interaction creates a new current version for an existing resource or
creates an initial version if no resource already exists for the given id.
The update
interaction is performed by an HTTP PUT
command as shown:
PUT [base]/[type]/[id] {?_format=[mime-type]}
The request body SHALL be a Resource with an id element
that has an identical value to the [id]
in the URL. If no id
element is provided, or
the value is wrong, the server SHALL respond with a HTTP 400
error code, and SHOULD
provide an operation outcome identifying the issue.
If the request body includes a meta
, the server SHALL
ignore the provided versionId
and lastUpdated
values.
If the server supports versions, it SHALL populate the meta.versionId
and meta.lastUpdated
with the new correct values. Servers are allowed to review and alter the other metadata values, but SHOULD refrain
from doing so (see metadata description for further information). Note that
there is no support for updating past versions - see notes on the history interaction.
A server SHOULD accept the resource as submitted when it accepts the update, and return the same
content when it is subsequently read. However systems may not be able to do this; see
the note on transactional integrity for discussion.
Also, see Variations between Submitted data and Retrieved data for additional discussion
around update behavior. Note that update
genreally updates the whole content of the resource. For partial
updates, see patch
below.
If the interaction is successful, the server SHALL return either a 200
OK HTTP status code if the resource was updated, or a 201
Created status code if the resource was created,
with a Last-Modified
header, and an ETag
header which contains the new versionId
of the resource. If the resource was created (i.e. the interaction resulted in a 201
Created), the server SHOULD
return a Location
header (this is for HTTP conformance; it's not otherwise needed).
Note: Servers MAY choose to preserve XML comments, instructions, and formatting or JSON whitespace when accepting updates, but are not required to do so. The impact of this on digital signatures may need to be considered.
Note that servers MAY choose to allow clients to PUT
a resource to a location that
does not yet exist on the server - effectively, allowing the client to define the
id of the resource. Whether a server allows this is a deployment choice based
on the nature of its relationships with the clients. While many servers will
not allow clients to define their ids, there are several reasons why it may
be necessary in some configurations:
Alternatively, clients may be sharing an agreed identification model (e.g. key server, scoped identifiers, or UUIDs) where clashes do not arise.
Servers can choose whether or not to support client defined ids, and indicate such to the clients using CapabilityStatement.rest.resource.updateCreate.
Servers are permitted to reject update interactions because of integrity concerns or other business rules, and return HTTP status codes accordingly (usually a 422
).
Common HTTP Status codes returned on FHIR-related errors (in addition to normal HTTP errors related to security, header and content type negotiation issues):
400
Bad Request - resource could not be parsed or failed basic FHIR validation rules (or multiple matches were found for 401
Not Authorized - authorization is required for the interaction that was attempted404
Not Found - resource type not supported, or not a FHIR end-point405
Method Not allowed - the resource did not exist prior to the update, and the server does not allow client defined ids409
/412
- version conflict management - see below422
Unprocessable Entity - the proposed resource violated applicable FHIR profiles or server business rulesAny of these errors SHOULD be accompanied by an OperationOutcome resource providing additional detail concerning the issue.
For additional information on how systems may behave when processing updates, refer to the Variations between Submitted data and Retrieved data page.
The conditional update interaction allows a client to update an existing resource based on some identification criteria,
rather than by logical id. To accomplish this, the client issues a PUT
as shown:
PUT [base]/[type]?[search parameters]
When the server processes this update, it performs a search using its standard search facilities for the resource type, with the goal of resolving a single logical id for this request. The action it takes depends on how many matches are found:
create
interaction412
Precondition Failed error indicating the client's criteria were not selective enough
This variant can be used to allow a stateless client (such as an interface engine) to submit
updated results to a server, without having to remember the logical ids that the server has assigned.
For example, a client updating the status of a lab result from "preliminary" to "final"
might submit the finalized result using PUT path/Observation?identifier=http://my-lab-system|123
Note that transactions and conditional create/update/delete are complex interactions and it is
not expected that every server will implement them. Servers that don't support the conditional
update should return an HTTP 400
error and an operation outcome.
Lost Updates , where two clients update the same resource, and the second overwrites the updates of the first, can be prevented using a combination of the ETag and If-Match header. This is also known as 'Optimistic Locking'.
To support this usage, servers SHOULD always return an ETag
header with each resource:
HTTP 200 OK Date: Sat, 09 Feb 2013 16:09:50 GMT Last-Modified: Sat, 02 Feb 2013 12:02:47 GMT ETag: W/"23" Content-Type: application/fhir+json
If provided, the value of the ETag SHALL match the value of the version id for the resource. Servers are allowed to generate the version id in whatever fashion that they wish, so long as they are valid according to the id data type, and are unique within the address space of all versions of the same resource. When resources are returned as part of a bundle, there is no ETag, and the versionId of the resource is used directly.
If the client wishes to request a version aware update, it submits the request with an
If-Match
header that quotes the ETag from the server:
PUT /Patient/347 HTTP/1.1 If-Match: W/"23"
If the version id given in the If-Match
header does not match, the server returns a
409 Conflict
status code instead of updating the resource.
Servers can require that clients provide an If-Match
header by returning 412 Pre-condition failed
status codes when no If-Match
header is found.
As an alternative to updating an entire resource, clients can perform a patch operation.
This can be useful when a client is seeking to minimise it's bandwidth utilization, or
in scenarios where a client has only partial access or support for a resource. The patch
interaction is performed by an HTTP PATCH
command as shown:
PATCH [base]/[type]/[id] {?_format=[mime-type]}
The body of a PATCH operation SHALL be either:
application/json-patch+json
application/xml-patch+xml
In either case, the server SHALL process it's own copy of the resource in the format indicated, applying
the operations specified in the document, following the relevant PATCH specification. When the operations
have all been processed, the server processes the resulting document as an Update
operation; all the version and error handling etc applies as specified, as does the Prefer Header.
Processing PATCH operations may be very version sensitive. For this reason, servers SHALL support conditional PATCH, which works exactly the same as specified for update in Concurrency Management. Clients SHOULD always consider using version specific PATCH operations so that inappropriate actions are not executed. In addition, servers SHALL support Conditional PATCH, which works exactly as described for Conditional Update.
The server SHALL ensure that the narrative in a resource is not clinically unsafe after the PATCH operation is performed. Exactly how this is defined and can be achieved depends on the context, and how narrative is being maintained, but servers may wish to consider:
generated
, the server could reject the PATCH operation
Processing XML Patch documents is tricky because of namespace handling. Servers SHALL handle
namespaces correctly, but note that FHIR resources only contain two XML namespaces,
for FHIR (http://hl7.org/fhir
) and XHTML (http://www.w3.org/1999/xhtml
).
For PATCH Examples, see (link todo).
Note: There is, as yet, no support for preforming patch operations as part of Batch or Transaction Operations. This may be addressed in a future version of the specification.
The delete
interaction removes an existing resource. The interaction
is performed by an HTTP DELETE
command as shown:
DELETE [base]/[type]/[id]
A delete interaction means that subsequent non-version specific reads of a resource
return a 410
HTTP status code and that the resource is no longer found through search
interactions. Upon successful deletion, or if the resource does not exist at all, the server should return either a
200 OK
if the response contains a payload, or a 204 No Content
with no response payload.
Whether to support delete at all, or for a particular resource type or a particular instance is at the
discretion of the server based on the business rules that apply in its context.
If the server refuses to delete resources of that type as a blanket policy, then it should return the 405
Method not allowed status code. If the server refuses to delete a resource because of reasons specific
to that resource, such as referential integrity, it should return the 409
Conflict status code.
Performing this interaction on a resource that is already deleted has no effect, and the server should return either a
200 OK
if the response contains a payload, or a 204 No Content
with no response payload.
Resources that have been deleted may be "brought back to life" by a subsequent update
interaction using an HTTP PUT
.
Many resources have a status element that overlaps with the idea of deletion. Each resource type defines what the semantics of the deletion interactions are. If no documentation is provided, the deletion interaction should be understood as deleting the record of the resource, with nothing about the state of the real-world corresponding resource implied.
For servers that maintain a version history, the delete
interaction does not remove a resource's version history. From a version history respect,
deleting a resource is the equivalent of creating a special kind of history entry that has
no content and is marked as deleted. Note that
there is no support for deleting past versions - see notes on the history interaction.
Since deleted resources may be brought back to life, servers MAY include an ETag on the delete response to allow version contention management when a resource is brought back to life.
The conditional delete interaction allows a client to delete an existing resource based on some selection criteria,
rather than by a specific logical id. To accomplish this, the client issues an HTTP DELETE
as shown:
DELETE [base]/[type]/?[search parameters]
When the server processes this delete, it performs a search as specified using the standard search facilities for the resource type. The action it takes depends on how many matches are found:
delete
on the matching resource412
Precondition Failed error indicating the client's criteria were not selective enough.
A server indicates whether it can delete multiple resources in its Capability Statement (.rest.resource.conditionalDelete).
if there are multiple matches, either all must deleted, or the server SHALL return an error
This variant can be used to allow a stateless client (such as an interface engine) to delete
a resource on a server, without having to remember the logical ids that the server has assigned.
For example, a client deleting a lab atomic result might delete the resource using DELETE /Observation?identifier=http://my-lab-system|123
.
Note that transactions and conditional create/update/delete are complex interactions and it is
not expected that every server will implement them. Servers that don't support the conditional
delete should return an HTTP 400
error and an operation outcome.
The create
interaction creates a new resource in a server-assigned location. If the client
wishes to have control over the id of a newly submitted resource, it should use the update
interaction instead. The create
interaction is performed by an HTTP POST
command as shown:
POST [base]/[type] {?_format=[mime-type]}
The request body SHALL be a FHIR Resource. The resource does not need to have an id
element (this is the
one of the few case where a resource exists without an id element). If an id
is provided, the
server SHALL ignore it. If the request body includes a meta, the server SHALL
ignore the existing versionId
and lastUpdated
values.
The server SHALL populate the id
, meta.versionId
and meta.lastUpdated
with the new correct values. Servers are allowed to review and alter the other metadata values, but SHOULD
refrain from doing so (see metadata description for further information).
A server SHOULD otherwise accept the resource as submitted when it accepts the create, and return the same content when it is subsequently read. However some systems may not be able to do this; see the note on transactional integrity for discussion.
The server returns a 201
Created HTTP status code, and SHALL also return a Location
header which
contains the new Logical Id and Version Id of
the created resource version:
Location: [base]/[type]/[id]/_history/[vid]
where [id]
and [vid]
are the newly created id and version id for the resource version.
Servers SHOULD return an ETag
header with the versionId (if versioning is supported) and a Last-Modified
header.
When the resource syntax or data is incorrect or invalid, and cannot be used to create a new resource, the server returns a 400
Bad Request HTTP status code.
When the server rejects the content of the resource because of business rules, the server returns a 422
Unprocessible Entity error HTTP status code.
In either case, the server SHOULD include a response body containing an OperationOutcome with detailed error messages describing the reason for the error.
Common HTTP Status codes returned on FHIR-related errors (in addition to normal HTTP errors related to security, header and content type negotiation issues):
400
Bad Request - resource could not be parsed or failed basic FHIR validation rules404
Not Found - resource type not supported, or not a FHIR end-point422
Unprocessable Entity - the proposed resource violated applicable FHIR profiles or server business rules. This should be accompanied by an OperationOutcome resource providing additional detailNote: Servers MAY choose to preserve XML comments, instructions, and formatting or JSON whitespace when accepting creates, but are not required to do so. The impact of this on digital signatures may need to be considered.
For additional information on how systems may behave when processing updates, refer to the Variations between Submitted data and Retrieved data page.
The conditional create
interaction allows a client to create a new resource only if some equivalent resource
does not already exist on the server. The client defines what equivalence means in this case by supplying
a FHIR search query using an HL7 defined extension header "If-None-Exist
" as shown:
If-None-Exist: [search parameters]
The parameter just contains the search parameters (what would be in the URL following the "?").
When the server processes this create, it performs a search as specified using its standard search facilities for the resource type. The action it takes depends on how many matches are found:
200
OK412
Precondition Failed error indicating the client's criteria were not selective enough
This variant can be used to avoid the risk of two clients
creating duplicate resources for the same record. For example, a client posting a new lab result might specify
If-None-Exist: identifier=http://my-lab-system|123
to ensure it is does not create a duplicate record.
Note that transactions and conditional create/update/delete are complex interactions and it is
not expected that every server will implement them. Servers that don't support the conditional
create should return an HTTP 412
error and an operation outcome.
This interaction searches a set of resources based on some filter criteria. The interaction can be performed by several different HTTP commands.
GET [base]/[type]{?[parameters]{&_format=[mime-type]}}
This searches all resources of a particular type using the criteria represented in the parameters.
Because of the way that some user agents and proxies treat GET
and POST
requests, in addition
to the get based search method above, servers that support search SHALL also support a POST
based search:
POST [base]/[type]/_search{?[parameters]{&_format=[mime-type]}}
This has exactly the same semantics as the equivalent GET
command. All these search interactions take a series of parameters that
are a series of name=value
pairs encoded in the URL (or as an application/x-www-form-urlencoded
submission for a POST
).
(See W3C HTML forms ).
Note:
application/x-www-form-urlencoded
is supported forPOST
so that invoking a search byGET
orPOST
can be done from HTML forms in a browser (though considerable active content might be required in the browser), although this is not the main usage.
Searches are processed as specified for the Search handling mechanism.
If the search fails (cannot be executed, not that there is no matches), the return value is
a status code 4xx or 5xx with an OperationOutcome.
If the search succeeds, the return content is a Bundle with
type = searchset
containing the results of the search as a list of resources
in a defined order. The result list can be long, so servers may use paging. If they do, they SHALL use the method described below
(adapted from RFC 5005 (Feed Paging and Archiving ) for breaking the
list into pages if appropriate. The server MAY also return an OperationOutcome resource with additional information about the search;
if one is sent it SHALL NOT include any errors, and it shall be marked with an entry
mode of include
.
To search a compartment, for either all possible resources or for a particular resource type, respectively:
GET [base]/[Compartment]/[id]/{*?[parameters]{&_format=[mime-type]}} GET [base]/[Compartment]/[id]/[type]{?[parameters]{&_format=[mime-type]}}
For example, to retrieve all the observation resources for a particular LOINC code associated with a particular encounter:
GET [base]/Encounter/23423445/Observation?code=2951-2 {&_format=[mime-type]}
Note that there are specific operations defined to support fetching an entire patient record or all record for an encounter.
It's also possible to search across multiple resource types:
GET [base]?_type=Condition,Observation&[parameters]{&_format=[mime-type]}
This is a request to search on both Condition and Observation. In this case,
the only parameters that can be used are those defined for both Condition and Observation
(using SearchParameter.base - see Cross-resource Search Parameters),
or the parameters defined for all resources. If a search lists types not listed SearchParameter.base
for any of the parameters, this is an error, and a server SHOULD return a 400 status. It's also possible to search on all types at once:
GET [base]?[parameters]{&_format=[mime-type]}
When searching all resources at once, only the parameters defined for all resources can be used.
The capabilities
interaction retrieves the server's Capability Statement that defines how it supports resources.
The interaction is performed by an HTTP GET
command as shown:
GET [base]/metadata {?_format=[mime-type]}
In addition, there is another method to get the capability statement, using the HTTP OPTIONS
command:
OPTIONS [base] {?_format=[mime-type]}
However as of STU3, this method is deprecated, and will be removed in a future version. Using OPTIONS like this is not conformant with HTTP, and creates challenges for cross-origin resource sharing support.
Applications SHALL return a Capability Statement that specifies which resource types and interactions are supported
for the GET
command. If a 404
Unknown is returned from the GET
, FHIR is not supported on the
nominated service url. An ETag
header SHOULD be returned with the CapabilityStatement. The value of the header SHALL change if the
CapabilityStatement itself changes. Additional parameters that are required to be returned with
the OPTIONS
command are defined in the OMG hData RESTful Transport specification.
The Capability statement returned typically has an arbitrary id, and no meta element, though it is not prohibited.
Capability statements can become quite large; Servers are encouraged to support the
_summary
and _elements
parameters on the capabilities interaction, though this is not required. In addition, servers are encouraged to
implement the $subset and $implements
operations to make it easy for a client to check conformance.
In addition to this capabilities
interaction, a server may also choose to provide the
standard set of interactions (read
, search
, create
, update
) defined on this page
for the CapabilityStatement Resource end-point.
This is different from the capabilities
interaction:
capabilities interaction | returns a capability statement describing the server's current operational functionality |
CapabilityStatement end-point | manages a repository of capability statements (e.g. the HL7 capability statement registry) |
All servers are required to support the capabilities
interaction, but servers may choose whether they wish to support the CapabilityStatement end-point,
just like any other end-point.
Implementation Note: In DSTU 2 and earlier, the resource that this interaction returned was named "Conformance". Clients often connect to a server, and use the
capabilities
interaction to check whether they are version and/or feature compatible with the server. Such clients should be able to process either a Conformance or a CapabilityStatement resource.
The batch
and transaction
interactions submit a set of actions to perform on a server in a single HTTP request/response.
The actions may be performed independently as a "batch", or as a single atomic "transaction" where
the entire set of changes succeed or fail as a single entity. Multiple actions on multiple resources
of the same or different types may be submitted, and they may be a mix of other interactions defined
on this page (e.g. read
, search
, create
, update
, delete
, etc.), or using the operations
framework.
The transaction
mode is especially useful where one would otherwise need multiple interactions, possibly
with a risk of loss of referential integrity if a later interaction fails (e.g. when storing
a Provenance resource and its corresponding target resource, or, on document repositories, a
document index entry and its accompanying document).
Note that transactions and conditional create/update/delete are complex interactions and it is not expected that every server will implement them.
A batch
or transaction
interaction is performed by an HTTP POST
command as shown:
POST [base] {?_format=[mime-type]}
The content of the post submission is a Bundle with Bundle.type = batch
or transaction
.
Each entry carries request
details (Bundle.entry.request)
that provides the HTTP details of the action in order to inform the system processing the batch or transaction
what to do for the entry (note: the request
is optional, but SHOULD be present). If the HTTP command is a PUT
or POST
, then the entry
SHALL contain a resource for the body of the action.
The resources in the bundle are each processed separately as if they were an individual
interactions or operations as otherwise described on this page, or the Operations
framework. The actions are subject to the normal processing for each,
including the meta element, verification and version aware updates,
and transactional integrity.
Examples:
For a batch
, there SHALL be no interdependencies between the different entries
in the Bundle that cause change on the server. The success or failure of one change SHOULD
not alter the success or failure or resulting content of another change. Servers SHOULD
validate that this is the case. Note that it is considered that servers execute the batch
in the same order as that specified below for transactions, though the order of execution
should not matter given the previous rule.
Static references within a Bundle.entry.resource another to Bundle.entry.resource that is being created within the Batch are be non-conformant.
For a transaction
, servers SHALL either accept all actions and return a 200
OK, along with a
response bundle (see below), or reject all resources and return an HTTP 400
or 500
type
response. It is not an error if the submitted bundle has no resources in it.
The outcome of the processing the transaction SHALL NOT depend on the order
of the resources in the transaction. A resource can only appear in a transaction
once (by identity).
Because of the rules that a transaction is atomic where all actions pass or fail together and the order of the entries doesn't matter, there is a particular order in which to process the actions:
DELETE
interactionsPOST
interactionsPUT
interactionsGET
interactionsIf any resource identities (including resolved identities from conditional update/delete) overlap in steps 1-3, then the transaction SHALL fail.
STU Note: clients are able to request that operations be executed as part of a transaction. Some transactions can cause side effects, such as the creation of new resources or other actions that may be difficult to fit into a transaction framework. Input regarding this issue is sought during the STU period.
Provide feedback here .
A transaction may include references from one resource to another in the bundle, including
circular references where resources refer to each other. If the server assigns
a new id to any resource in the bundle as part of the processing rules above,
it SHALL also update any references to that resource in the same bundle as they
are processed. References to resources that are not
part of the bundle are left untouched. Version-specific references should remain
as version-specific references after the references have been updated.
Servers SHALL replace all matching links in the bundle, whether they are found in the resource ids,
resource references, url elements, or <a href="" & <img src=""
in the narrative.
When processing a "POST" (create), the full URL is treated as the id of the resource on the source, and is ignored; the server generates an id for the resource. For updates, the server performs a mapping between the fullUrl specified and the local URL the server knows that instance as, if possible. If the server does not have a mapping for the fullUrl, the server ignores the base URL and attempts an update assuming the base is the same as the server base. This allows the same transaction bundle to be sent to multiple systems without changing the fullUrls for each target.
When processing a batch or transaction, a server MAY choose to honor existing
logical ids (e.g. Observation/1234
remains as Observation/1234
on the server), but
since this is only safe in controlled circumstances, servers
may choose to assign new ids to all submitted resources, irrespective of any claimed
logical id
in the resource, or fullUrl
on entries in the batch/transaction.
Note: this behavior is subject to verification based on implementation experience and may change.
Conditional References
When constructing the bundle, the client may not know the logical id of a resource, but it may know identifying information - e.g. an identifier. This situations arises commonly when building transactions from v2 messages. The client could resolve that identifier to a logical id using a search, but that would mean that the resolution to a logical id does not occur within the same transaction as the commit (as well as significantly complicating the client). Because of this, in a transaction (and only in a transaction), references to resources may be replaced by a search URI that describes how to find the correct reference:
<Bundle xmlns="http://hl7.org/fhir"> <id value="20160113160203" /> <type value="transaction" /> <entry> <fullUrl value="urn:uuid:c72aa430-2ddc-456e-7a09-dea8264671d8" /> <resource> <Observation> <subject> <reference value="Patient?identifier=12345"/> </subject> <--! rest of resource omitted --> </Observation> </resource> <request> <method value="POST" /> </request> </entry> <Bundle>
The search URI is relative to the servers [base] path, and always starts with
a resource type: [type]:?parameters...
. Only filtering parameters
are allowed; none of the parameters that control the return of resources
are relevant.
When processing transactions, servers SHALL:
For a batch, or a successful transaction, the response the server SHALL
return a Bundle with type
set to batch-response
or transaction-response
that contains one entry for each entry in the
request, in the same order, with the outcome of processing the entry. For a failed transaction,
the server returns a single OperationOutcome instead of a Bundle.
A client may use the return bundled to track the outcomes of processing the entry,
and the identities assigned to the resources by the server. Each entry element SHALL
contain a response
element which details the outcome of processing the
entry - the HTTP status code, and the location and ETag
header values,
which are used for identifying and versioning the resources. In addition, a resource
may be included in the entry, as specified by the Prefer header.
A server may choose to accept bundle types other than batch
or transaction
when POST
ed to the [base] URL.
Bundles of type history
inherently have the same structure as a transaction
, and
can be treated as either a transaction or batch, so servers SHOULD accept a history bundle - this makes it
possible to replicate data from one server to another easily using a pub/sub model. Note, however, that
the original transaction boundaries may not represented in a history list, and
a resource may occur more than once in a history list, so
servers processing history bundles must have some strategy to manage this.
For other bundle types, should the server choose to accept them, there will be
no request
element (note that every entry will have a resource).
In this case, the server treats the entry as either a create or an update interaction,
depending on whether it recognises the identity of the resource - if the identity
of the resource refers to a valid location on the server, it should treat it
as an update to that location. Note: this option allows a client to delegate
the matching process to the server.
The history interaction retrieves the history of either a particular resource, all resources of
a given type, or all resources supported by the system. These three variations of the history
interaction are performed by HTTP GET
command as shown:
GET [base]/[type]/[id]/_history{?[parameters]&_format=[mime-type]} GET [base]/[type]/_history{?[parameters]&_format=[mime-type]} GET [base]/_history{?[parameters]&_format=[mime-type]}
The return content is a Bundle with
type set to history
containing the
specified version history, sorted with oldest versions last, and including deleted resources.
Each entry SHALL minimally contain either a resource
which holds the resource as
it is at the conclusion of the interaction, or a request
with entry.request.method
The request
provides information about the interaction that occurred to
cause the new version, and allows, for instance, subscriber system to differentiate between
create and update interactions. The principal reason a resource
might be missing
is that the resource was changed by some other channel rather than via the RESTful interface. If
the entry.request.method
is a PUT
or a POST
, the entry
SHALL contain a resource.
The interactions create
, update
, and delete
create history entries. Other interactions do not (note that these operations may produce side-effects
such as new AuditEvent resources; these are represented as create interactions in their own right).
New resources or updates to existing resources that are triggered by operations also appear in the
history, as do updates to the resources that result from interactions outside the scope of the
RESTful interface.
A create interaction is represented in a history interaction in the following way:
<entry> <resource> <Patient> <!-- the id of the created resource --> <id value="23424"/> <!-- snip --> </Patient> </resource> <request> <!-- POST: this was a create --> <method value="POST"/> <url value="Patient"/> </request> </entry>
Note that conditional creates, updates and deletes are converted to direct updates and deletes in a history list.
In addition to the standard _format
parameter, the parameters to this interaction may also include:
_count : integer | single | Number of return records requested. The server is not bound to return the number requested, but cannot return more |
_since : instant | single | Only include resource versions that were created at or after the given instant in time |
_at : dateTime | single | Only include resource versions that were current at some point during the time period specified in the date time value (may be more than one) |
The history list can be restricted to a limited period by specifying a _since
parameter which contains a full date time with time zone.
Clients should be aware that due to timing imprecision, they may receive notifications of a resource update on the boundary instant more than once. Servers are
not required to support a precision finer than by second.
The updates list can be long, so servers may use paging. If they do, they SHALL use the method described below for breaking the list into pages if appropriate, and maintain the specified _count across pages.
The history interaction can be used to set up a subscription from one system to another, so that resources are synchronized between them. Refer to the Subscription resource for an alternate means of system synchronization.
Additional Notes about maintaining a history of resources:
When processing create and update interactions, a FHIR server is not obliged to accept the entire resource as it is; when the resource is retrieved through a read interaction subsequently, the resource may be different. The difference may arise for several reasons:
Note that there is no general purpose method to make merging with existing content or altering the content by business rules safe or predictable - what is possible, safe and/or required is highly context dependent. These kinds of behaviors may be driven by security considerations. With regard to incomplete support, clients can consult the server's base Capability statement profile references to determine which features or values the server does not support.
To the degree that the server alters the resource for any of the 3 reasons above, the FHIR server will create implementation consequences for the eco-system that it is part of, which will need to be managed (i.e. it will cost more). For this reason, servers SHOULD change the resource as little as possible, given the constraints of the system exposing the FHIR resource. However due to the variability that exists within healthcare, this specification allows that servers MAY alter the resource on create/update.
Similarly, to the degree that an implementation context makes special rules about merging content or altering the content, that context will become more expensive to maintain.
Although these rules are stated with regard to servers, a similar concept applies to clients - to the degree that different client systems interacting with the server do not support the same feature set, the clients and/or the server will be forced to implement custom logic to prevent information from being lost or corrupted.
Some of these problems can be mitigated by following a pattern built on top of version-aware updates. In this pattern:
read
interaction for any resource it accepts update
interactions onread
s the latest version of the resourceupdate
interaction, and is able to handle a 409
or 412
response (usually by trying again)If clients follow this pattern, then information from other systems that they do not understand will be maintained through the update.
Note that it's possible for a server to choose to maintain the information that would be lost, but there is no defined way for a server to determine whether the client omitted the information because it wasn't supported (perhaps in this case) or whether it wishes to delete the information.
Both client and server systems SHOULD clearly document how transaction integrity is handled.
STU Note: For now, the only way to document how transaction integrity is handled is as text in the narrative portions of the CapabilityStatement resource. Feedback during the Trial use period on what - if any - of this information should be computable is welcome.
Provide feedback here .
If servers provide paging for the results of a search or history interaction,
they SHALL conform to this method (adapted from RFC 5005 (Feed
Paging and Archiving) for sending continuation links to the client when returning a Bundle
(e.g. with history
and search
). If the server does not do this then there is no way to continue paging.
This example shows the third page of a search result:
<Bundle xmlns="http://hl7.org/fhir"> <!-- snip metadata --> <!-- This Search. url starts with base search, and adds the effective parameters, and additional parameters for search state. All searches SHALL return this value. In this case, the search continuation method is that the server maintains a state, with page references into the stateful list. --> <link> <relation value="self"> <url value="http://example.org/Patient?name=peter&stateid=23&page=3"/> </link> <!-- 4 links for navigation in the search. All of these are optional, but recommended --> <link> <relation value="first"/> <url value="http://example.org/Patient?name=peter&stateid=23&page=1"/> </link> <link> <relation value="previous"/> <url value="http://example.org/Patient?name=peter&stateid=23&page=2"/> </link> <link> <relation value="next"/> <url value="http://example.org/Patient?name=peter&stateid=23&page=4"/> </link> <link> <relation value="last"/> <url value="http://example.org/Patient?name=peter&stateid=23&page=26"/> </link> <!-- then the search results... --> </Bundle>
The server need not use a stateful paging method as shown in this example - it is at the discretion of the server how to best ensure that the continuation retains integrity in the context of ongoing changes to the resources. An alternative approach is to use version specific references to the records on the boundaries, but this is subject to continuity failures when records are updated.
A server MAY add additional state tracking parameters to the links, as shown in the example above. The client must use the server supplied links in order to traverse the pages. A server MAY inform the client of the total number of resources returned by the interaction for which the results are paged using the Bundle.total.
Note that for search, where _include can be used to return additional related resources, the total number of resources in the feed may exceed the number indicated in totalResults.
The HTTP protocol may be routed through an HTTP proxy such as squid. Such proxies are transparent to the applications, though implementers should be alert to the effects of caching, particularly including the risk of receiving stale content. See the HTTP specification for further detail
Interface engines may also be placed between the consumer and the provider. These differ from proxies because they actively alter the content and/or destination of the HTTP exchange and are not bound the rules that apply to HTTP proxies. Such agents are allowed, but SHALL mark the HTTP header to assist with troubleshooting.
Any agent that modifies an HTTP request or response content other than under the rules for HTTP proxies SHALL add a stamp to the HTTP headers like this:
request-modified-[identity]: [purpose] response-modified-[identity]: [purpose]
The identity SHALL be a single token defined by the administrator of the agent that will sufficiently identify the agent in the context of use. The header SHALL specify the agent's purpose in modifying the content. End point systems SHALL not use this header for any purpose. Its aim is to assist with system troubleshooting.
This RESTful specification described here is based on the OMG Health RESTful specification (HData) . In this regard, FHIR functions as a Record Format Profile as described in that specification. Note the following significant factors to be aware of:
POST
to service URL), POST
to the service URL has been re-used for the transaction
interaction (difference under review)OPTIONS
command on the service URL
These tables present a summary of the interactions described here.
Note that all requests may include an optional Accept
header to indicate the format used for the response (this is even true for DELETE
since an OperationOutcome may be returned).
Interaction | Path | Request | ||||
---|---|---|---|---|---|---|
Verb | Content-Type | Body | Prefer | Conditional | ||
read | /[type]/[id] | GET | N/A | N/A | N/A | O: ETag , If-Modified-Since , If-None-Match |
vread | /[type]/[id]/_history/[vid] | GET | N/A | N/A | N/A | N/A |
update | /[type]/[id] | PUT | R | Resource | O | O: If-Match |
delete | /[type]/[id] | DELETE | N/A | N/A | N/A | N/A |
create |
| POST | R | Resource | O | O: If-None-Exist |
search | /[type]? | GET | N/A | N/A | N/A | N/A |
/[type]/_search? | POST | application/x-www-form-urlencoded | form data | N/A | N/A | |
search-all | ? | GET | N/A | N/A | N/A | N/A |
capabilities | /metadata | GET | N/A | N/A | N/A | N/A |
transaction | / | POST | R | Bundle | O | N/A |
history | /[type]/[id]/_history | GET | N/A | N/A | N/A | N/A |
history-type | /[type]/_history | GET | N/A | N/A | N/A | N/A |
history-all | /_history | GET | N/A | N/A | N/A | N/A |
(operation) | /$[name] , /[type]/$[name]
or /[type]/[id]/$[name] | POST | R | Parameters | N/A | N/A |
GET | N/A | N/A | N/A | N/A | ||
POST | application/x-www-form-urlencoded | form data | N/A | N/A |
Notes:
Interaction | Response | |||||
---|---|---|---|---|---|---|
Content-Type | Body | Location | Versioning | Status Codes | ||
read | R | R: Resource | N/A | R: ETag , Last-Modified | 200 , 404 , 410 | |
vread | R | R: Resource | N/A | R: ETag , Last-Modified | 200 , 404 | |
update | R if body | O: Resource (Prefer) | R on create | R: ETag , Last-Modified | 200 , 201 , 400 , 404 , 405 , 409 , 412 , 422 | |
delete | R if body | O: OperationOutcome | N/A | N/A | 200 , 204 , 404 , 405 , 409 , 412 | |
create | R if body | O : Resource (Prefer) | R | R: ETag , Last-Modified | 201 , 400 , 404 , 405 , 422 | |
search | R | R: Bundle | N/A | N/A | 200 , 401 ? | |
search-all | R | R: Bundle | N/A | N/A | 200 , 401 ? | |
capabilities | R | R: CapabilityStatement | N/A | N/A | 200 , 404 | |
transaction | R | R: Bundle | N/A | N/A | 200 , 400 , 404 , 405 , 409 , 412 , 422 | |
history | R | R: Bundle | N/A | N/A | 200 | |
history-type | R | R: Bundle | N/A | N/A | 200 | |
history-all | R | R: Bundle | N/A | N/A | 200 | |
(operation) | R | R: Parameters/Resource | N/A | N/A | 200 |
Note: this table lists the status codes described here, but other status codes are possible as described by the HTTP specification. Additional codes that are likely are server errors and various codes associated with authentication protocols.