IPA-111: Server-Modified Values and Defaults
Server-modified and default values often make it harder to implement state-driven clients. These clients are often unable to tell when their desired state matches the current state for these fields, as the rules by which a server may modify and return values are complex, not public, and not repeatable.
Adopt
Guidance
Single Owner Fields
Fields must have a single owner, whether that is the client or the server.
- Server-owned fields are fields that are controlled and modified by the service
- Client-owned fields are fields that are controlled by the client
- All fields that are not explicitly documented as server-owned must be considered client-owned
- The server must respect the value (or lack thereof) of all client-owned fields and not modify them
- The server must always return the same value the client sent (or absence of value) for client-owned fields
For resources where all fields are server-owned, see read-only resources and read-only singleton resources.
Effective Values
There are instances where a service will allocate, generate, or calculate a value that may differ from what the client specified.
An attribute with an effective value must be expressed as two fields in the API:
- A client-owned mutable field that may be optionally set by the user and must not be modified by the service
- A server-owned read-only field that records the effective value decided on
by the service
- Effective values must be named by prefixing
effectiveto the mutable field's name - In OpenAPI, the effective value field must have
readOnly: true
- Effective values must be named by prefixing
Example
A cluster's instance size may have a different computed value from the server if auto-scaling is enabled. The client specifies their desired instance size, but the server may scale it up or down based on load.
// For managing a cluster with auto-scaling enabled
{
"instanceSize": "M10",
"effectiveInstanceSize": "M30"
}
Boolean Values
- Booleans should default to
false- Many serialization systems won’t distinguish
falsevalues from unset values which introduces complications when a boolean defaults totrue
- Many serialization systems won’t distinguish
Example
package example
// Bad
// Given the go struct
type ClusterDescriptionProcessArgs struct {
JavascriptEnabled bool `json:"javascriptEnabled"`
}
// the following call will default to false and requires user intervention to set
// JavascriptEnabled to true
sdk.UpdateClusterAdvancedConfiguration(new(ClusterDescriptionProcessArgs))
// Users need to always set the true value even if the API defaults to true
sdk.UpdateClusterAdvancedConfiguration(&ClusterDescriptionProcessArgs{JavascriptEnabled: true}))
// Good
type ClusterDescriptionProcessArgs struct {
JavascriptDisabled bool `json:"javascriptEnabled"`
}
// the following call will default to false and requires user intervention to set
// JavascriptDisabled to true
sdk.UpdateClusterAdvancedConfiguration(new(ClusterDescriptionProcessArgs))