Manage a FHIR Resource Through Its Lifecycle

Create, read, update, read a prior version of, and logically delete a DDFS FHIR resource.

This scenario follows one Patient through the standard FHIR create, read, update, versioned read (vread), and delete interactions. The requests use the FHIR R4 (4.0.1) API surface. Use the same interaction pattern on the FHIR R6 ballot4 (6.0.0-ballot4) surface only when its deployed capability statement advertises the resource and interaction.

A standard DELETE performs a logical delete. Permanent deletion is a separate administrative workflow and is not part of ordinary CRUD processing.

Prerequisites

  • Call GET /api/fhir/r4/metadata and confirm that Patient advertises create, read, update, vread, and delete.
  • Use an OAuth access token with the permissions required for each interaction.
  • Use a unique identifier value so that the example resource can be distinguished from other Patient resources.
  • Retain the logical ID and version IDs returned by the service. The examples use {rid} and {vid} placeholders.

Workflow

StepInteractionResult
1CreateThe service assigns a logical ID and initial version.
2ReadThe service returns the current version.
3UpdateThe service creates a new version of the same logical resource.
4Versioned readThe service returns the requested historical version.
5DeleteThe service logically deletes the resource without permanently erasing its stored history.

Examples

1. Create the Patient

The Prefer: return=representation header requests the response resource because this example consumes the response body.

POST /api/fhir/r4/Patient
Accept: application/fhir+json
Content-Type: application/fhir+json
Prefer: return=representation

{
  "resourceType": "Patient",
  "identifier": [
    {
      "system": "urn:example:patient-identifier",
      "value": "{unique-id}"
    }
  ],
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Test",
      "given": ["Lifecycle"]
    }
  ],
  "gender": "unknown",
  "birthDate": "1970-01-01"
}

Example response:

201 Created
ETag: W/"1"
Location: /api/fhir/r4/Patient/{rid}/_history/{vid}
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "{rid}",
  "meta": {
    "versionId": "1",
    "lastUpdated": "{timestamp}"
  },
  "identifier": [
    {
      "system": "urn:example:patient-identifier",
      "value": "{unique-id}"
    }
  ],
  "active": true,
  "name": [
    {
      "use": "official",
      "family": "Test",
      "given": ["Lifecycle"]
    }
  ],
  "gender": "unknown",
  "birthDate": "1970-01-01"
}

Save {rid} from the assigned id and save the initial version ID from meta.versionId, ETag, or the versioned Location.

2. Read the Current Version

GET /api/fhir/r4/Patient/{rid}
Accept: application/fhir+json

Example response:

200 OK
ETag: W/"1"
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "{rid}",
  "meta": {"versionId": "1", "lastUpdated": "{timestamp}"},
  "active": true,
  "birthDate": "1970-01-01"
}

3. Update the Patient

Send the complete replacement resource with the logical ID in both the request path and body. This example changes active and preserves the other data.

PUT /api/fhir/r4/Patient/{rid}
Accept: application/fhir+json
Content-Type: application/fhir+json
Prefer: return=representation

{
  "resourceType": "Patient",
  "id": "{rid}",
  "identifier": [
    {
      "system": "urn:example:patient-identifier",
      "value": "{unique-id}"
    }
  ],
  "active": false,
  "name": [
    {
      "use": "official",
      "family": "Test",
      "given": ["Lifecycle"]
    }
  ],
  "gender": "unknown",
  "birthDate": "1970-01-01"
}

Example response:

200 OK
ETag: W/"2"
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "{rid}",
  "meta": {"versionId": "2", "lastUpdated": "{timestamp}"},
  "active": false,
  "birthDate": "1970-01-01"
}

4. Read the Prior Version

Use the initial version ID saved after creation. A versioned read retrieves that historical version; it does not return the current version.

GET /api/fhir/r4/Patient/{rid}/_history/{vid}
Accept: application/fhir+json

Example response for the initial version:

200 OK
ETag: W/"1"
Content-Type: application/fhir+json

{
  "resourceType": "Patient",
  "id": "{rid}",
  "meta": {"versionId": "1", "lastUpdated": "{timestamp}"},
  "active": true,
  "birthDate": "1970-01-01"
}

5. Logically Delete the Patient

DELETE /api/fhir/r4/Patient/{rid} performs a logical delete. A successful request returns no response body.

DELETE /api/fhir/r4/Patient/{rid}
Accept: application/fhir+json
204 No Content

After deletion, do not continue to use the resource as an active record. Handle a subsequent read according to the FHIR status and OperationOutcome returned by the service.

Permanent Deletion Is a Separate Administrative Workflow

A logical delete is distinct from both permanent-deletion operations:

  • POST /api/fhir/r4/Patient/{rid}/$hardDelete permanently deletes one logically deleted Patient.
  • POST /api/fhir/r4/Patient/$purgeDeleted permanently deletes eligible logically deleted Patient resources selected by the operation inputs.

Both operations are irreversible and require additional authorization. Confirm that the resource is eligible and review Permanently Deleting FHIR Resources before using either operation.

Status Codes

CodeMeaning
200A read, update, or versioned read completed successfully and returned the resource.
201The resource was created successfully.
204The resource was logically deleted successfully and the response has no body.