Lesson 39 of 51 · The RESTful API

Operations and the CapabilityStatement

FHIR RESTful API

Create, read, update, delete, and search cover the great majority of what a FHIR client needs. But some tasks do not fit that mold — validating a resource against its rules, gathering everything known about one patient, expanding a value set — and some clients need to discover what a given server can actually do before they call it. FHIR answers both needs with two mechanisms: operations, which extend behavior beyond plain REST, and the CapabilityStatement, which lets a server declare what it supports.

Operations

When an interaction does not map cleanly onto CRUD or search, FHIR defines a named operation. Operations are invoked with a leading $ in the URL, which distinguishes them from ordinary resource paths and makes them unmistakable 1. They are RPC-style: rather than reading or writing a resource directly, a client calls a named procedure that the server runs and returns a result for.

An operation can be defined at three levels 1:

  • System level[base]/$op — not tied to any resource type, such as a server-wide function.
  • Type level[base]/[type]/$op — applies to a whole resource type.
  • Instance level[base]/[type]/[id]/$op — applies to one specific resource.

Inputs and outputs are commonly carried in a special resource called Parameters, which exists precisely to package the named arguments an operation expects and the values it returns 1. Because operations frequently take structured input, most are invoked with POST, carrying a Parameters body; some simple operations whose inputs are just a few primitive values may also be invoked with GET, passing those values in the URL 1.

Several operations are well established across the ecosystem. $validate checks whether a resource conforms to the relevant rules and profiles. $everything — for example, Patient/$everything — gathers the resources related to a single record into one Bundle. And the terminology operation $expand enumerates the codes in a value set; it is covered fully in the terminology lesson. The key idea is that operations are the official, governed way to add behavior that plain REST cannot express, without bending or breaking the REST model itself 1.

# Instance-level operation: everything about one patient
GET [base]/Patient/123/$everything

# Type-level operation with structured input, sent as POST
POST [base]/Observation/$validate
Content-Type: application/fhir+json

{ "resourceType": "Parameters", "parameter": [ ... ] }

CapabilityStatement

A client should not have to guess what a server supports. The CapabilityStatement is a resource that a server publishes to declare exactly that, and it is conventionally fetched from a fixed endpoint 1:

GET [base]/metadata

The statement describes, in machine-readable form, what the endpoint can do 1:

  • The FHIR version the server implements, and the profiles it claims to support.
  • Which resource types are available.
  • Which interactions each type supports — read, create, update, delete, search, and so on.
  • Which search parameters are recognized for each type.
  • Which operations the server exposes.

A client uses the CapabilityStatement for discovery: before relying on a feature, it can fetch /metadata, confirm the server speaks the expected FHIR version, and check that the resource types, search parameters, or operations it needs are present. This turns integration from trial-and-error into a deterministic check.

In effect, the CapabilityStatement functions as a machine-readable contract for the endpoint. It states what a caller may expect and what the server promises to honor, much as a v2 message profile or an implementation guide documents the expectations between trading partners — except that here the contract is itself a FHIR resource a program can read and act on automatically 1.

Putting it together

Operations and the CapabilityStatement are complementary. Operations widen what a server can do beyond plain REST, in a governed and predictable way; the CapabilityStatement lets a client learn which of those capabilities — and which resource types, interactions, and search parameters — a particular server actually offers. Together they let independently built systems negotiate and interoperate without prior coordination, which is the central promise of a FHIR REST API.

References

  1. HL7 FHIR Release 4 (R4), v4.0.1. HL7 International. 2019. verified Cited at: operations.html; capabilitystatement.html.