Skip to content

Support the FHIR PATCH interaction (FHIRPath Patch)#553

Open
schwzr wants to merge 1 commit into
developfrom
issue/552_Support_FHIR_PATCH
Open

Support the FHIR PATCH interaction (FHIRPath Patch)#553
schwzr wants to merge 1 commit into
developfrom
issue/552_Support_FHIR_PATCH

Conversation

@schwzr

@schwzr schwzr commented Jul 26, 2026

Copy link
Copy Markdown
Member

Closes #552

Summary

Adds support for the FHIR PATCH interaction using the FHIRPath Patch format (a Parameters resource, https://www.hl7.org/fhir/R4/fhirpatch.html):

  • Direct REST: PATCH [type]/[id] and conditional PATCH [type]?[criteria]
  • Inside transaction and batch bundles (Bundle.entry.request.method = PATCH)
  • Advertised as a supported interaction in the CapabilityStatement

A patch is applied to a copy of the current resource and then written through the existing update code path, so authorization (reasonUpdateAllowed(old, patched)), validation, optimistic locking (If-Match), versioning and the Prefer header behave exactly as for an update. PATCH maps to the existing UPDATE role — no new permission is required.

Implementation

  • FhirPathPatchService — new engine applying add / insert / delete / replace / move on the HAPI R4 runtime model (FhirContext / IFhirPath). No new runtime dependency — deliberately avoids hapi-fhir-storage (which would pull in hapi-fhir-server, JPA/Hibernate, Quartz, Spring-tx).
  • REST: new @PATCH JAX-RS annotation (JAX-RS ships none), patch(...) on BasicResourceService and the abstract jaxrs / secure / impl layers. The patch service is provided through the already-injected ParameterConverter singleton to avoid threading a new constructor argument through all ~28 resource services.
  • Bundle: new PatchCommand (resolves the target DAO from the request URL like DeleteCommand, transaction priority 3 like update) plus a PATCH branch in CommandFactoryImpl and the audit log.
  • Client: FhirWebserviceClient.patch(...) / patchConditionaly(...).

Scope

In scope: FHIRPath Patch (add / insert / delete / replace / move), REST (standard + conditional), transaction + batch bundles, client support, tests.

Out of scope (for now):

  • JSON Patch (application/json-patch+json) and XML Patch — omitted to keep the dependency footprint minimal; FHIRPath Patch is also the format FHIR recommends for FHIR resources. Can be added later.
  • Resolving temporary (urn:uuid:) references contained inside patch values when processed within a bundle.

Testing

  • Unit testsFhirPathPatchServiceImplTest: 12/12 (all five operation types incl. list mutation and error handling).
  • Integration testsPatchIntegrationTest: 5/5 (REST, conditional, transaction bundle, 404 not-found, 400 bad-request) against a real server + PostgreSQL (Testcontainers).
  • Regression — full server unit suite 231/231 green; full FHIR integration suite 496/497 green. The single failure is the pre-existing flaky ParallelCreateIntegrationTest#testCreateDuplicateStructureDefinitionsParallelDirect (a parallel race test): it passes on develop and passes/fails intermittently on this branch (~50%), and this change touches no create / DAO / unique-constraint code.

🤖 Generated with Claude Code

Implements the FHIR PATCH interaction using the FHIRPath Patch format
(Parameters resource), both as a direct REST interaction
(PATCH [type]/[id] and conditional PATCH [type]?[criteria]) and inside
transaction and batch bundles.

- new FhirPathPatchService applies add/insert/delete/replace/move on the
  HAPI R4 runtime model without an additional dependency (no
  hapi-fhir-storage), using the FHIRPath engine already on the classpath
- patch reuses the existing update code path, so authorization
  (reasonUpdateAllowed), validation, optimistic locking (If-Match),
  versioning and the Prefer header behave identically to an update
- new PatchCommand plus PATCH dispatch in CommandFactoryImpl for bundle
  processing, patch branch added to the audit log
- 'patch' interaction added to the CapabilityStatement
- FhirWebserviceClient patch(...) and patchConditionaly(...)
- unit tests for the patch engine, integration tests for REST, conditional
  and bundle patch including not-found and bad-request handling

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant