Skip to content

Add optional conditional requests (ETag, If-Match, If-None-Match) - #704

Open
aaronzi wants to merge 1 commit into
IDTA-01002-3-3_workingfrom
aaronzi/691-conditional-requests
Open

aaronzi wants to merge 1 commit into
IDTA-01002-3-3_workingfrom
aaronzi/691-conditional-requests

Conversation

@aaronzi

@aaronzi aaronzi commented Oct 21, 2026

Copy link
Copy Markdown
Member

Closes #691

Adds HTTP conditional requests (RFC 9110) to the HTTP/REST API. Clients can use them to detect concurrent changes of a resource ("lost updates") and to revalidate representations they already have. As agreed in the API task force, the feature is optional and not bound to a profile. Existing servers and clients remain conformant.

Normative behavior

  • Optional for servers. Only a server that returns an ETag for a resource has to evaluate If-Match / If-None-Match for that resource. A server without support returns no ETag and may ignore the headers.
  • Optional for clients. A server shall not reject a request because it has no precondition, so 428 Precondition Required is intentionally not part of the spec. Clients shall work with servers that return no entity tags, and shall not assume protection without having received an ETag.
  • Minimum guarantee. Strong entity tags. The entity tag changes whenever the resource or one of its nested elements changes. A nested element may share the entity tag of its containing resource, e.g. a SubmodelElement and its Submodel. Different representations returned to different clients, e.g. due to access rules, have different tags.
  • Writes. PUT, PATCH, POST below an existing resource and DELETE accept If-Match. A mismatch returns 412 with a Result object and leaves the resource unchanged, and the check is atomic with the change. If-None-Match: * on PUT means create-only.
  • Reads. GET accepts If-None-Match and answers 304 only for authorized requests.
  • Precedence. 400/401/403/404 take precedence over 412 (RFC 9110, 13.2.1).
  • Scope. Single resources and their parts in all service specifications, including superpaths. Out of scope: paginated lists, queries, bulk operations, /description, /serialization, $signed, $history, operation invocation and its status/result endpoints, and the async AASX endpoints.

OpenAPI ("check how this affects swagger")

  • New reusable components in Part2-API-Schemas/openapi.yaml:
    • header ETag
    • parameters IfMatch and IfNoneMatch (both required: false)
    • responses not-modified and precondition-failed
  • 382 operation entries in all SSP files and the Entire-API-Collection reference them:
    • GET: If-None-Match, ETag on 200, and 304
    • PUT: If-Match, If-None-Match and 412. No ETag on PUT responses (RFC 9110, 9.3.4)
    • PATCH/POST: If-Match, ETag on 2xx, and 412
    • DELETE: If-Match and 412
  • Effect on code generation: generated servers and clients get two optional header parameters for these operations. A server can ignore them, and a client can omit them. A short note is in the API Code Generation clause.
  • The edit adds lines only. A check that removes the additions again reproduces every original file exactly, and all files pass OpenAPI 3.0 validation.

Documentation

  • New clause Conditional Requests in the HTTP/REST API chapter, with an example, plus a bullet in Design Decisions
  • Generic status codes SuccessNotModified (304) and ClientPreconditionFailed (412) in the status code table and the HTTP mapping table
  • Note in the Profiles clause that the feature is not represented by a profile
  • Terms "conditional request" and "entity tag", abbreviation CORS, RFC 9110 in the bibliography
  • Conformance test cases HTTP.cond.001–006
  • Changelog: new section "Changes w.r.t. V3.2 to V3.3"

Notes for merging

…ne-Match)

Add RFC 9110 conditional requests to the HTTP/REST API so that clients can
detect concurrent changes of a resource and revalidate representations.
Support is optional for servers and clients and not bound to a profile.

- New clause "Conditional Requests" in the HTTP/REST API chapter
- Generic status codes SuccessNotModified (304) and ClientPreconditionFailed (412)
- Shared OpenAPI components ETag, IfMatch, IfNoneMatch, not-modified and
  precondition-failed in the Part 2 schemas, referenced as optional elements
  by the single-resource operations of all profiles and the Entire-API-Collection
- Notes on profiles and code generation, terms, bibliography, conformance
  test cases and changelog

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants