Skip to main content

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.

State

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
    • Server-owned fields must be documented as read-only
    • In OpenAPI, server-owned fields must have readOnly: true
    • Server-owned fields must not be accepted in request bodies for Create or Update operations
  • 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
note

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 effective to the mutable field's name
    • In OpenAPI, the effective value field must have readOnly: true

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 false values from unset values which introduces complications when a boolean defaults to true

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))