From a1549496ee31d2a79b160745ef2a307062d74995 Mon Sep 17 00:00:00 2001 From: Eric Tune Date: Tue, 13 Oct 2015 12:42:49 -0700 Subject: [PATCH] Documented required/optional fields. --- docs/devel/api-conventions.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/devel/api-conventions.md b/docs/devel/api-conventions.md index 7ad1dbc6a48..710fff51f09 100644 --- a/docs/devel/api-conventions.md +++ b/docs/devel/api-conventions.md @@ -59,6 +59,7 @@ using resources with kubectl can be found in [Working with resources](../user-gu - [List Operations](#list-operations) - [Map Operations](#map-operations) - [Idempotency](#idempotency) + - [Optional vs Required](#optional-vs-required) - [Defaulting](#defaulting) - [Late Initialization](#late-initialization) - [Concurrency Control and Consistency](#concurrency-control-and-consistency) @@ -370,6 +371,38 @@ All compatible Kubernetes APIs MUST support "name idempotency" and respond with Names generated by the system may be requested using `metadata.generateName`. GenerateName indicates that the name should be made unique by the server prior to persisting it. A non-empty value for the field indicates the name will be made unique (and the name returned to the client will be different than the name passed). The value of this field will be combined with a unique suffix on the server if the Name field has not been provided. The provided value must be valid within the rules for Name, and may be truncated by the length of the suffix required to make the value unique on the server. If this field is specified, and Name is not present, the server will NOT return a 409 if the generated name exists - instead, it will either return 201 Created or 504 with Reason `ServerTimeout` indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header). +## Optional vs Required + +Fields must be either optional or required. + +Optional fields have the following properties: + +- They have `omitempty` struct tag in Go. +- They are a pointer type in the Go definition (e.g. `bool *awesomeFlag`). +- The API server should allow POSTing and PUTing a resource with this field unset. + +Required fields have the opposite properties, namely: + +- They do not have an `omitempty` struct tag. +- They are not a pointer type in the Go definition (e.g. `bool otherFlag`). +- The API server should not allow POSTing or PUTing a resource with this field unset. + +Using the `omitempty` tag causes swagger documentation to reflect that the field is optional. + +Using a pointer allows distinguishing unset from the zero value for that type. +There are some cases where, in principle, a pointer is not needed for an optional field +since the zero value is forbidden, and thus imples unset. There are examples of this in the +codebase. However: + +- it can be difficult for implementors to anticipate all cases where an empty value might need to be + distinguished from a zero value +- structs are not omitted from encoder output even where omitempty is specified, which is messy; +- having a pointer consistently imply optional is clearer for users of the Go language client, and any + other clients that use corresponding types + +Therefore, we ask that pointers always be used with optional fields. + + ## Defaulting Default resource values are API version-specific, and they are applied during