@@ -51,10 +51,10 @@ services in a backward-compatible way:
5151 make sure that all constraints are clearly defined in description.
5252* `enum` ranges can be reduced when used as input parameters, only if the server
5353 is ready to accept and handle old range values too. The range can be reduced
54- when used as output parameters.
54+ when used only as output parameters.
5555* `enum` ranges cannot be extended when used for output parameters — clients may
56- not be prepared to handle it. However, enum ranges can be extended when used
57- for input parameters.
56+ not be prepared to handle it. However, ` enum` ranges can be extended when used
57+ only for input parameters.
5858* You <<112>> that are used for output parameters and likely to
5959 be extended with growing functionality. The API definition should be updated
6060 first before returning new values.
@@ -124,8 +124,11 @@ Service clients should apply the robustness principle:
124124 http://martinfowler.com/bliki/TolerantReader.html["TolerantReader"] post),
125125 i.e. ignore new fields but do not eliminate them from payload if needed for
126126 subsequent {PUT} requests.
127- ** Be prepared that {x-extensible-enum} return parameters (see <<112, rule 112>>) may deliver new values;
128- either be agnostic or provide default behavior for unknown values, and do not eliminate them.
127+ ** Be prepared that "extensible enum" return parameters (see <<112, rule 112>>)
128+ may deliver new values;
129+ either be agnostic or provide default behavior for unknown values, and
130+ do not eliminate them if needed for subsequent {PUT} requests.
131+ (This means you can't simply map it to a limited enumeration type like a Java `enum`.)
129132** Be prepared to handle HTTP status codes not explicitly specified in endpoint
130133 definitions. Note also, that status codes are extensible. Default handling is
131134 how you would treat the corresponding {x00} code (see
@@ -289,46 +292,90 @@ level data structures, since they don't support compatible, future extensions.
289292
290293
291294[#112]
292- == {SHOULD} use open-ended list of values (`x-extensible-enum `) for enumeration types
295+ == {SHOULD} use open-ended list of values (via `examples `) for enumeration types
293296
294297JSON schema `enum` is per definition a closed set of values that is assumed to be
295- complete and not intended for extension. This closed principle of enumerations
296- imposes compatibility issues when an enumeration must be extended. To avoid
297- these issues, we recommend to use an open-ended list of values instead
298- of an enumeration unless:
298+ complete and not intended for extension. This means, extending the list of values of
299+ `enum` is considered an incompatible change, and needs to be aligned with all consumers
300+ as other incompatible changes.
301+
302+ To avoid these issues, we recommend to use `enum` only if
299303
3003041. the API has full control of the enumeration values, i.e. the list of values
301305 does not depend on any external tool or interface, and
3023062. the list of values is complete with respect to any thinkable and unthinkable
303307 future feature.
304308
305- To specify an open-ended list of values via the {x-extensible-enum} property as follows:
309+ In all other cases, where additional values are imaginable our recommendation is this:
310+
311+ * Use `examples` with the list of currently known values
312+ * Put "Extensible enum" in the description.
313+
314+ This indicates that currently these listed values will be possible, but
315+ consumers need to be aware that this list can be extended without notice
316+ (see below for details).
306317
307318[source,yaml]
308319----
309- delivery_methods :
320+ delivery_method :
310321 type: string
311- x-extensible-enum :
322+ examples :
312323 - PARCEL
313324 - LETTER
314325 - EMAIL
326+ description: Extensible enum. The chosen delivery method of the invoice.
315327----
316328
317- *Note:* {x-extensible-enum} is a proprietary extension of the JSON Schema standard that
318- is e.g. visible via Swagger UI, but ignored by most other tools.
319-
320329See <<240>> about enum value naming conventions.
321330
322- Note, {x-extensible-enum} is a different concept than JSON schema `examples` which is
323- just a list of a few example values, whereas {x-extensible-enum} defines all valid
324- values (for a specific API and service version) and has the advantage of an extensible
325- full type-range specification that is validated by the service.
331+ **Important**:
332+
333+ * API consumers must be prepared for the fact that also other values can be returned
334+ with server responses (or be contained in consumed events), and implement a
335+ fallback / default behavior for unknown new values, see <<108>>.
336+ * API owners must take care to extend these extensible enums in a compatible way, i.e.
337+ not changing the semantics of already existing / documented values.
338+ * For uses in input, API implementations should validate the values and only accept
339+ values listed in `examples`. The list should not be reduced (that would be an incompatible change).
340+ * Before additional values are accepted or returned, API owners should extend
341+ the `examples` list, see <<107>>.
342+
343+ (Note that the last 3 bullet points do not apply for uses of `examples` _without_ the
344+ "Extensible enum" marker in the description – here any value at all needs
345+ to be expected.)
346+
347+ === Historic Note
348+
349+ Previously (until May 2025), this guideline recommended our own proprietary
350+ {x-extensible-enum} JSON schema extension here, with a similar semantic:
351+
352+ > This is the *complete* list of values *currently* possible, but consumers must be
353+ prepared for other values in the future.
354+
355+ Until all existing APIs using this have been updated, API providers and consumers
356+ still need to follow the rules under "Important" above for these cases.
357+
358+ This completeness semantic would in theory allow some validation by
359+ intermediaries (but that was rarely implemented).
360+ It was visible in a few tools (e.g. Swagger UI), but ignored by most others.
361+
362+ An open-ended list of values was specified as follows:
363+
364+ [source,yaml]
365+ ----
366+ delivery_methods:
367+ type: string
368+ x-extensible-enum:
369+ - PARCEL
370+ - LETTER
371+ - EMAIL
372+ description: The chosen delivery method of the invoice.
373+ ----
326374
327- *Important:* Clients must be prepared for extensions of enums returned with server responses, i.e.
328- must implement a fallback / default behavior to handle unknown new enum values -- see <<108>>.
329- API owners must take care to extend enums in a compatible way that does not change the
330- semantics of already existing enum values, for instance, do not split an old enum value
331- into two new enum values. Services should only extend {x-extensible-enum} ranges, and only accept
332- and return values listed in the API definition, i.e. the API definition needs to be updated first
333- before the service accepts/returns new values -- see also <<107>>.
375+ This rule originated in the time before JSON schema and OpenAPI schema
376+ had the plural `examples` property (OpenAPI schema had singular `example`,
377+ JSON schema had neither).
334378
379+ We also thought we could have some validations (e.g. by our event bus Nakadi),
380+ but the Nakadi team instead decided to not validate `x-extensible-enum`,
381+ and even reject it in schema definitions.
0 commit comments