Skip to content

Support conditional create-on-update via If-None-Match #2050

@lmsurpre

Description

@lmsurpre

Is your feature request related to a problem? Please describe.
In #160 we added support for conditional read via If-None-Match.

However, this header is also useful on the update/create-on-update side. Specifically, it can be used to avoid creating the same resource multiple times.

Describe the solution you'd like
Clients can pass the If-None-Match header to us in their PUT request.
If If-None-Match is set to * and a resource exists at the passed location, then no update performed.

Describe alternatives you've considered
The spec defines a conditional create via a custom If-None-Exists header that is based on FHIR search. We support that today, but it would be extremely hard to get the locking right if we want to guarantee no duplicates (see #2051).

Acceptance Criteria
1.
GIVEN a PUT to [base]/Observation/123
WHEN the If-None-Match header is set to *
AND a resource (any version) already exists at [base]/Observation/123
THEN the response status is HTTP 304 (Not Modified)
AND the response body is set according to the Prefer: return preference (representation=the existing resource, minimal=empty, OperationOutcome=a short description of why the resource wasn't updated)

GIVEN a PUT to [base]/Observation/123
WHEN the If-None-Match header is set to W/"1"
AND a resource with version "1" already exists at [base]/Observation/123
THEN the response status is HTTP 500 (Server Error)
AND the response body is set according to the Prefer: return preference (minimal=empty, OperationOutcome=a description of the error explaining that If-None-Match with a specific version is not supported)

GIVEN a PUT to [base]/Observation/123
WHEN the If-None-Match header is set to *
AND no resource exists at [base]/Observation/123
THEN the response status is HTTP 201 (Created)
AND the response body is set according to the Prefer: return preference (representation=the newly created resource, minimal=empty, OperationOutcome=any warnings or informational messages from validating the new resource version)

GIVEN a PUT to [base]/Observation/123
WHEN the If-None-Match header is not passed
AND a resource exists (any version) at [base]/Observation/123
THEN the response status is HTTP 200 (OK)
AND the response body is set according to the Prefer: return preference (representation=the newly updated resource, minimal=empty, OperationOutcome=any warnings or informational messages from validating the new resource version)

GIVEN a PUT to [base]/Observation/123
WHEN the If-None-Match header is set to *
AND a deleted resource exists at [base]/Observation/123
THEN the response status is HTTP 201 (Created)
AND the response body is set according to the Prefer: return preference (representation=the newly created resource, minimal=empty, OperationOutcome=any warnings or informational messages from validating the new resource version)

Additional context
See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match

Specifically, the part about If-None-Match: *

The asterisk is a special value representing any resource. They are only useful when uploading a resource, usually with PUT, to check if another resource with the identity has already been uploaded before.

Metadata

Metadata

Assignees

Labels

P3Priority 3 - Nice To Havebreaking-change-javaIdentifies a change in a method signature that an implementer may use.enhancementNew feature or requestshowcaseUsed to Identify End-of-Sprint Demos

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions