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.
Experimental
Guidance
Single Owner Fields
Fields must have a single owner, whether that is the client or the server. Server-owned fields must be documented as such. All other types of fields must be considered to be owned by the client. The server must respect the value (or lack thereof) of all client-owned fields and not modify them.
Effective Values
There are instances where a service will allocate, generate, or calculate a value if the client chooses not to specify one.
For example: a client creates a cluster without specifying a version. Such a scenario is opting for the default mongodb version.
An attribute with an effective value must be expressed as two fields in the API:
- A mutable field that may be optionally set by the user and must not be modified by the service
- A 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
Example
// For managing autoscaling of a cluster
{
"clusterTier": "M10",
"effectiveClusterTier": "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 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))