summaryrefslogtreecommitdiff
path: root/api_changes.md
diff options
context:
space:
mode:
Diffstat (limited to 'api_changes.md')
-rw-r--r--api_changes.md75
1 files changed, 58 insertions, 17 deletions
diff --git a/api_changes.md b/api_changes.md
index 687af00a..72c38b7f 100644
--- a/api_changes.md
+++ b/api_changes.md
@@ -33,6 +33,13 @@ Documentation for other releases can be found at
# So you want to change the API?
+Before attempting a change to the API, you should familiarize yourself
+with a number of existing API types and with the [API
+conventions](api-conventions.md). If creating a new API
+type/resource, we also recommend that you first send a PR containing
+just a proposal for the new API types, and that you initially target
+the experimental API (pkg/expapi).
+
The Kubernetes API has two major components - the internal structures and
the versioned APIs. The versioned APIs are intended to be stable, while the
internal structures are implemented to best reflect the needs of the Kubernetes
@@ -92,9 +99,12 @@ backward-compatibly.
Before talking about how to make API changes, it is worthwhile to clarify what
we mean by API compatibility. An API change is considered backward-compatible
if it:
- * adds new functionality that is not required for correct behavior
- * does not change existing semantics
- * does not change existing defaults
+ * adds new functionality that is not required for correct behavior (e.g.,
+ does not add a new required field)
+ * does not change existing semantics, including:
+ * default values and behavior
+ * interpretation of existing API types, fields, and values
+ * which fields are required and which are not
Put another way:
@@ -104,11 +114,11 @@ Put another way:
degrade behavior) when issued against servers that do not include your change.
3. It must be possible to round-trip your change (convert to different API
versions and back) with no loss of information.
+4. Existing clients need not be aware of your change in order for them to continue
+ to function as they did previously, even when your change is utilized
If your change does not meet these criteria, it is not considered strictly
-compatible. There are times when this might be OK, but mostly we want changes
-that meet this definition. If you think you need to break compatibility, you
-should talk to the Kubernetes team first.
+compatible.
Let's consider some examples. In a hypothetical API (assume we're at version
v6), the `Frobber` struct looks something like this:
@@ -179,14 +189,43 @@ API call might POST an object in API v7beta1 format, which uses the cleaner
form (since v7beta1 is "beta"). When the user reads the object back in the
v7beta1 API it would be unacceptable to have lost all but `Params[0]`. This
means that, even though it is ugly, a compatible change must be made to the v6
-API.
+API. However, this is very challenging to do correctly. It generally requires
+multiple representations of the same information in the same API resource, which
+need to be kept in sync in the event that either is changed. However, if
+the new representation is more expressive than the old, this breaks
+backward compatibility, since clients that only understood the old representation
+would not be aware of the new representation nor its semantics. Examples of
+proposals that have run into this challenge include [generalized label
+selectors](http://issues.k8s.io/341) and [pod-level security
+context](http://prs.k8s.io/12823).
As another interesting example, enumerated values provide a unique challenge.
Adding a new value to an enumerated set is *not* a compatible change. Clients
which assume they know how to handle all possible values of a given field will
not be able to handle the new values. However, removing value from an
enumerated set *can* be a compatible change, if handled properly (treat the
-removed value as deprecated but allowed).
+removed value as deprecated but allowed). This is actually a special case of
+a new representation, discussed above.
+
+## Incompatible API changes
+
+There are times when this might be OK, but mostly we want changes that
+meet this definition. If you think you need to break compatibility,
+you should talk to the Kubernetes team first.
+
+Breaking compatibility of a beta or stable API version, such as v1, is unacceptable.
+Compatibility for experimental or alpha APIs is not strictly required, but
+breaking compatibility should not be done lightly, as it disrupts all users of the
+feature. Experimental APIs may be removed. Alpha and beta API versions may be deprecated
+and eventually removed wholesale, as described in the [versioning document](../design/versioning.md).
+Document incompatible changes across API versions under the [conversion tips](../api.md).
+
+If your change is going to be backward incompatible or might be a breaking change for API
+consumers, please send an announcement to `kubernetes-dev@googlegroups.com` before
+the change gets in. If you are unsure, ask. Also make sure that the change gets documented in
+the release notes for the next release by labeling the PR with the "release-note" github label.
+
+If you found that your change accidentally broke clients, it should be reverted.
## Changing versioned APIs
@@ -199,10 +238,13 @@ before starting "all the rest".
### Edit types.go
The struct definitions for each API are in `pkg/api/<version>/types.go`. Edit
-those files to reflect the change you want to make. Note that all non-online
-fields in versioned APIs must have description tags - these are used to generate
+those files to reflect the change you want to make. Note that all types and non-inline
+fields in versioned APIs must be preceded by descriptive comments - these are used to generate
documentation.
+Optional fields should have the `,omitempty` json tag; fields are interpreted as being
+required otherwise.
+
### Edit defaults.go
If your change includes new fields for which you will need default values, you
@@ -228,6 +270,12 @@ incompatible change you might or might not want to do this now, but you will
have to do more later. The files you want are
`pkg/api/<version>/conversion.go` and `pkg/api/<version>/conversion_test.go`.
+Note that the conversion machinery doesn't generically handle conversion of values,
+such as various kinds of field references and API constants. [The client
+library](../../pkg/client/unversioned/request.go) has custom conversion code for
+field references. You also need to add a call to api.Scheme.AddFieldLabelConversionFunc
+with a mapping function that understands supported translations.
+
## Changing the internal structures
Now it is time to change the internal structs so your versioned changes can be
@@ -365,13 +413,6 @@ hack/update-swagger-spec.sh
The API spec changes should be in a commit separate from your other changes.
-## Incompatible API changes
-
-If your change is going to be backward incompatible or might be a breaking change for API
-consumers, please send an announcement to `kubernetes-dev@googlegroups.com` before
-the change gets in. If you are unsure, ask. Also make sure that the change gets documented in
-`CHANGELOG.md` for the next release.
-
## Adding new REST objects
TODO(smarterclayton): write this.