diff --git a/chapters/compatibility.adoc b/chapters/compatibility.adoc index 533bc1a3..cdf4c06b 100644 --- a/chapters/compatibility.adoc +++ b/chapters/compatibility.adoc @@ -41,25 +41,63 @@ expected that code changes are necessary. == {SHOULD} prefer compatible extensions API designers should apply the following rules to evolve RESTful APIs for -services in a backward-compatible way: +services in a backward-compatible way. + +In general: -* Add only optional, never mandatory fields. * Never change the semantic of fields (e.g. changing the semantic from customer-number to customer-id, as both are different unique customer keys) +* Consider <<251>> in case a URL has to change. + +The compatibility of schema changes depends on whether the input and/or output objects are defined. + +For schemas used in input only: + +* Add optional fields, but never mandatory fields. +* Make mandatory fields optional, but not vice-versa. +* Don't remove fields(*). * Input fields may have (complex) constraints being validated via server-side business logic. Never change the validation logic to be more restrictive and make sure that all constraints are clearly defined in description. -* `enum` ranges can be reduced when used as input parameters, only if the server - is ready to accept and handle old range values too. The range can be reduced - when used only as output parameters. -* `enum` ranges cannot be extended when used for output parameters — clients may - not be prepared to handle it. However, `enum` ranges can be extended when used - only for input parameters. +* `enum` ranges can be reduced, only if the server + continues to accept and handle old range values. +* `enum` ranges can be extended. + +(*) Hint: Removing a field can be considered as a compatible change that does not break clients, in case the service still accepts and possibly ignores it if sent by the client. However, removed fields allow later adding a same-named field with different type or semantic (which is harder to catch). We therefore define field removal as non-compatible. + +For schemas used in output only: + +* Add (mandatory or optional) fields. +* Make optional fields mandatory, but not vice-versa. +* Don't remove fields (*). +* `enum` ranges can be reduced. +* `enum` ranges *cannot* be extended — clients may + not be prepared to handle it. * You <<112>> that are used for output parameters and likely to be extended with growing functionality. The API specification should be updated first before returning new values. -* Consider <<251>> in case a URL has to change. +(*) Hint: Removing an optional field can be considered as a compatible change that does not break clients. However, removed fields allow later adding a same-named field with different type or semantic (which is harder to catch). We therefore define optional field removal as non-compatible. + +For schemas used in both input and output (which is typical in +many cases), both of these rule sets combine, i.e. you can only do changes which +are allowed in both input and output. + +* Add only optional, never mandatory fields. +* Don't remove any fields. +* Don't make mandatory fields optional or make optional fields mandatory. +* Input fields may have (complex) constraints being validated via server-side + business logic. Never change the validation logic to be more restrictive and + make sure that all constraints are clearly defined in description. +* `enum` ranges can be reduced only if the server is ready to still accept and + handle old values. They **cannot** be extended. +* You <<112>> that are used for output parameters and likely to + be extended with growing functionality. The API definition should be updated + first before returning new values. + +Input/Output here is from the perspective of a service implementing and +owning the API. For the rare case of APIs implemented by other services +(and consumed by the owning service), this turns around. [#109] == {SHOULD} design APIs conservatively