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.
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-Matchheader to us in their PUT request.If
If-None-Matchis 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-Existsheader 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-Matchheader 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: returnpreference (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-Matchheader is set toW/"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: returnpreference (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-Matchheader 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: returnpreference (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-Matchheader is not passedAND 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: returnpreference (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-Matchheader 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: returnpreference (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: *