Resource IDs
Every FHIR resource stored in the repository has a resource ID. This ID is a logical identifier that will never change for the life of the resource.
Consider the following resource:
http://try.smilecdr.com:8000/baseR4/Patient/d62d9d82-3f2b-44db-b807-04159be709fb
In this example, the resource identity (i.e. the complete URL) is often referred to by its relative URL of Patient/987
. The URL has the following parts:
http://try.smilecdr.com:8000/baseR4
Patient
d62d9d82-3f2b-44db-b807-04159be709fb
A common source of confusion for newcomers to FHIR is the distinction between resource IDs and resource identifiers. Despite the similar names, these are not the same thing.
A resource ID is the portion of the resource address/URL that comes after the resource type. For example, the resource Patient/123
has the ID of 123. This ID should be treated like a database primary key: it is an internal identifier that will not change. Every resource can only have one ID.
On the other hand, an identifier (such as the field Patient.identifier
) is a business identifier. Most resources with identifiers support repetition on this field, meaning that the resource can have multiple identifiers. Identifiers have a namespace (e.g. Patient.identifier.system
) and a value (e.g. Patient.identifier.value
):
http://hl7.org/fhir/sid/us-ssn
as being the system for US Social Security Numbers.If you have a use case involving identifiers that should be marked as unique, see Enforcing Uniqueness for information on how to achieve this.
In most cases, resources will receive an ID that is assigned by the server when they are created. This ID is generated automatically by the server.
The algorithm used to define IDs can be controlled using the dao_config.server_id_mode
configuration property.
This property accepts the following values:
In this mode, each resource created on the server will receive a numeric ID assigned in sequence. For example, if the first two resources created on the server are a Patient followed by an Observation, these two resources will receive the IDs Patient/1
and Observation/2
. This is the default configuration.
In this mode, each resource created on the server will receive a randomly generated UUID. This mode is often useful in situations where you wish to replicate resources from one server to another, and want to avoid resource ID collisions.
The FHIR specification allows clients to supply IDs for newly created resources as well (reference).
Client assigned IDs are performed using an HTTP PUT (i.e. a FHIR "update"). Note that when using an HTTP POST (i.e. a FHIR "create") the server will always assign the resource ID.
For example, consider the following client operation:
PUT /Patient/A123
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"id":"A123"
}
In this example, if a resource already exists on the server with the ID A123
then it will be updated. If no resource already exists on the server with the ID A123
then a new resource will be created with this ID.
The dao_config.client_id_mode
property may be set to control what IDs are allowable as client assigned IDs.
In this mode, clients may not assign a resource ID. Attempts to write to a resource ID that does not already exist will result in an HTTP 412 Precondition Failed.
In this mode, clients may assign IDs and there is no restriction on what these IDs may be, aside from the FHIR rules for valid resource IDs. If this mode is selected, it is highly recommended to use the UUID
Server ID Mode if this is selected, in order to avoid any potential conflicts between client assigned numeric IDs, and IDs that are automatically generated by the server using a database sequence.
In alphanumeric mode, clients may assign any ID except for purely numeric IDs. Purely numeric IDs are reserved for assignment by the server. This mode is the default.
In other words, a client will not be allowed to create a new resource with the ID Patient/123
, as this ID is reserved in the pool of IDs used by the server when it assigns IDs. A client will be permitted to create a resource with any of the following IDs: Patient/P123
, Patient/ABC
, Patient/1.2.3
, etc.
This behaviour has implications if you are synchronizing or replicating resources between two FHIR servers since IDs generated in the source repository may not be acceptable in the target repository.
When replicating, there are several common approaches to ensuring that resources can replicate successfully:
Patient/123
with patient Patient/ACME-123
) is acceptable, and can also provide a hint to the provenance of the source resource. See the note on ID prefixes in REST Hook Subscriptions for one example of how to achieve this.UUID
server ID mode is selected (see above) then there will be no issue using server generated IDs in the target server.This setting is the default because it provides slightly better performance than the ANY
setting in environments where most IDs are server-assigned. You should change this only if you do not want to allow client-assigned IDs or if you need to be able to handle client-assigned IDs that are purely numeric.
Clients are not permitted to assign IDs. If an update (HTTP PUT) is performed against an ID that does not exist on the server, the client will receive an HTTP 404 Not Found.
Clients are allowed to assign any valid FHIR IDs. This means that clients may use both alphanumeric IDs (e.g. "A100" and "ABC") as well as purely numeric IDs such as "1234".
When this value is used, it is highly recommended to set the Server Assigned IDs mode to UUID
in order to avoid any possibility of conflicts.