R4 Draft for Comment

This page is part of the FHIR Specification (v3.2.0: R4 Ballot 1). 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 GroupMaturity Level: 5Ballot Status: Normative

Normative Candidate Note: This page is candidate normative content for R4 in the Infrastructure Package. Once normative, it will lose it's Maturity Level, and breaking changes will no longer be made.

The RESTful API defines a set of common interactions (read, update, search, etc.) performed on a repository of typed resources. These interactions follow the RESTful paradigm of managing state by Create/Read/Update/Delete actions on a set of identified resources. While this approach solves many use cases, there is some specific functionality that can be met more efficiently using an RPC-like paradigm, where named operations are performed with inputs and outputs (Execute). 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. This specification describes a lightweight operation framework that seamlessly extends the RESTful API.

Operations have the following general properties:

  • Each operation has a name
  • Each operation has a list of 'in' and 'out' parameters
  • Parameters are either resources, data types, or search parameters
  • Operations are subject to the same security constraints and requirements as the RESTful API
  • The URIs for the operation end-points are based on the existing RESTful API address scheme
  • Operations may make use of the existing repository of resources in their definitions
  • Operations may be performed on a specific resource, a resource type, or a whole system

Operations are executed using a URL derived from the FHIR endpoint, where the name of the operations is prefixed by a "dollar sign" ('$') character. For example:

 POST http://fhir.someserver.org/fhir/Patient/1/$everything

When an operation has affectsState = false, and the parameters are all primitive data types with no extensions (as is the case with the example above), it may be invoked using GET as well. (Note: A HEAD request can also be used - see Support for HEAD).

Operations can be invoked on four types of FHIR endpoints:

  • The "base" FHIR service endpoint (e.g. http://fhir.someserver.org/fhir): These are operations that operate on the full scale of the server. For example, "return me all extensions known by this server"
  • A Resource type (e.g. http://fhir.someserver.org/fhir/Patient): These are operations that operate across all instances of a given resource type
  • A Resource instance (e.g. http://fhir.someserver.org/fhir/Patient/1): These are operations that involve only a single instance of a Resource, like the $everything operation above does
  • A specific version of a resource instance (http://fhir.someserver.org/fhir/Patient/1/_history/4): These operations involve only a specific version of a single instance of a FHIR Resource and exists only to allow manipulation of profile and tag metadata of past versions

The body of the invocation contains a special infrastructure resource called Parameters, which represents a collection of named parameters as <key,value> pairs, where the value may be any primitive or complex datatype or even a full Resource. It may also include strings formatted as search parameter types.

Upon completion, the operation returns another Parameters resource, containing one or more output parameters. This means that a FHIR operation can take a set of zero or more parameters in and return a set of zero or more result parameters out. Both the body of the POST and the returned result are always a Resource.

Some Operations with primitive input types and a single Resource output parameter named 'return' can be invoked using a GET directly, with parameters as HTTP URL parameters. In this case, the response is simply the resource that is the return value, with no Parameters resource. These kinds of usage are discussed further below.

Executing operations without any parameters is a special case. For an operation that doesn't cause any state change, the operation is invoked in a straight forward fashion:

GET [base]/Composition/example/$document

For operations that call state changes, they most be invoked by a POST. There is no parameters resource in this case because a parameters resource cannot be empty. So the operation is invoked with a POST with an empty body:

POST [base]/Claim/example/$submit
Content-Length: 0


See the list of defined operations.

Implementations are able to define their own operations in addition to those defined here. Name clashes between operations defined by different implementers can be resolved by the use of the server's Capability Statement.

Also, the definition of these or additional run time operations does not prevent the use of other kinds of operations that are not dependent on and/or not integrated with the RESTful API, provided that their addressing scheme does not clash with the scheme defined here.

Each Operation is defined by:

  • A context for the Operation - system, resource type, or resource instance
  • A name for the Operation
  • A list of parameters along with their definitions

For each parameter, the following information is needed:

  • Name - the name of the parameter. For implementer convenience, the name should be a valid token (see below)
  • Use - In | Out | Both
  • Type - a data type or a Resource type
  • Search Type - for string search parameters, what kind of search parameter they are (& and what kind of modifiers they have)
  • Profile - a StructureDefinition that applies additional restrictions about the resource
  • Documentation - a description of the parameter's use
  • (Optional) Search Type - if the type is a string, and the parameter is being used like a search parameter, which kind of search type applies

Parameters may be nested into multi-part parameters. Each part has the same information as a parameter, except for use, which is taken from the parameter it is part of.

The resource Operation Definition is used to provide a computable definition of the Operation.

Implementations are able to extend an operation by defining new named parameters. Implementations can publish their own extended definitions using the Operation Definition resource, and this variant definition can use OperationDefinition.base to refer to the underlying definition.

Note that the FHIR specification will never define any parameter names starting with "x-".

Operations are typically executed synchronously: a client sends a request to a server that includes the operation's in parameters and the server replies with the operation's out parameters.

The URL for an operation end-point depends on its context:

  • system: the URL is [base]/$[name]
  • resource type: the URL is [base]/[type]/$[name]
  • resource instance: the URL is [base]/[type]/[id]/$[name]

An operation is generally invoked by performing an HTTP POST to the operation's end-point. The submitted content is the special Parameters format (the "in" parameters) - a list of named parameters. For an example, see the value set expansion request example. Note that when parameters have a search type, the search modifiers are available, and are used on the parameter name in the Parameters resource (e.g. "code:in").

Note that the same arrangement as for the RESTful interface applies with respect to content types.

If all the parameters for the operation are primitive types, and the operation has affectsState = false (see HTTP specification definition of idempotent ), the operation may be invoked by performing an HTTP GET operation where all of the values of the parameters are appended to the URL in the search portion of the URL (e.g. after the '?' character). Servers SHALL support this method of invocation. E.g.

GET [base]/ValueSet/$expand?url=http://hl7.org/fhir/ValueSet/body-sit&filter=abdo

When using the HTTP GET operation, if there is a repeating parameter for the extended operation the values for that parameter are repeated by repeating the named parameter. E.g. Observation $stats statistic parameter

GET [base]/Observation/$stats?subject=Patient/123&code=55284-4&system=http://loinc.org&duration=1&statistic=average&statistic=min&statistic=max&statistic=count

If, when invoking the operation, there is exactly one input parameter of type Resource (irrespective of whether other possible parameters are defined), that the operation can also be executed by a POST with that resource as the body of the request (and no parameters on the url).

Servers MAY choose to support submission of the parameters represented in multi-part/form-data format as well, which can be useful when testing an operation using HTML forms.

If an operation succeeds, an HTTP Status success code is returned. This will usually be a 2xx code, though it may also be a 303 See Other. Other kinds of 3xx codes should be understood to indicate that the operation did not proceed, and the client will need to re-issue the operation if it can perform the redirection (e.g. may get redirected to an authentication step). User agents should note that servers may issue redirects, etc. to authenticate the client in response to an operation request. An HTTP status code of 4xx or 5xx indicates an error, and an OperationOutcome SHOULD be returned with details.

In general, an operation response uses the same Parameters format whether there is only one or there are multiple named out parameters.

If there is only one out parameter, which is a Resource with the parameter name "return" then the parameter format is not used, and the response is simply the resource itself.

The resources that are returned by the operation may be retained and made available in the resource repository on the operation server. In that case, the server will provide the identity of the resource in the returned resources. When resources that are not persisted are returned in the response, they will have no id property.

Use the standard RESTful API Asynchronous pattern to execute operations asynchrously.