States
Many API resources carry a concept of “state”: ordinarily, the resource’s place in its lifecycle. For example, a virtual machine may be being provisioned, available for use, being spun down, or potentially be in one of several other situations. A job or query may be preparing to run, be actively running, have completed, and so on.
Guidance
Resources needing to communicate their state should use an enum, which
should be called State
(or, if more specificity is required, end in the
word State
). This enum should be nested within the message it describes
when only used as a field within that message.
Enum values
Ideally, APIs use the same terminology throughout when expressing the same semantic concepts. There are usually many words available to express a given state, but our customers often use multiple APIs together, and it is easier for them when our terms are consistent.
At a high level:
- Resources that are available for use are
ACTIVE
(preferred over terms such as “ready” or “available”). - Resources that have completed a (usually terminal) requested action use past
participles (usually ending in
-ED
), such asSUCCEEDED
(not “successful”),FAILED
(not “failure”),DELETED
,SUSPENDED
, and so on. - Resources that are currently undergoing a state change use present
participles (usually ending in
-ING
), such asRUNNING
,CREATING
,DELETING
, and so on. In this case, it is expected that the state is temporary and will resolve to another state on its own, with no further user action.
Output only
The field referencing the State
enum in a resource must behave and be
documented as “Output only”, in accordance with
field behavior documentation.
APIs must not allow a State
enum to be directly updated through an
“update” method (or directly set through the “create” method), and must
instead use custom state transition methods.
This is because update methods are generally not expected to have side effects, and also because updating state directly implies that it is possible to set the state to any available value, whereas states generally reflect a resource’s progression through a lifecycle.
State transition methods
State transition methods are a special type of
custom method that are responsible for transitioning a
state field from one enum value to another. As part of the transition, other
fields may also change, e.g. an update_time
field. In addition to the general
guidance for custom methods on resources, the following guidance applies for
method definitions:
- The name of the method should be a verb followed by the singular form of the resource’s message name.
- The HTTP verb must be
POST
.
In addition to the general guidance for custom methods on resources, the following guidance applies for request definitions:
- A resource path field must be included. It should be called
path
. - The comment for the field should document the resource pattern.
- Other fields may be included.
- The request message must match the RPC name, with a
Request
suffix. - The response message should be the resource itself.
- If the RPC is long-running, the response message should be an
aep.api.Operation
which resolves to the resource itself.
- If the RPC is long-running, the response message should be an
- The
body
clause in thegoogle.api.http
annotation must be"*"
. - The request message field receiving the resource path should map to the
URI path.
- This field should be called
path
. - The
path
field should be the only variable in the URI path. All remaining parameters should map to URI query parameters.
- This field should be called
- If the state transition is not allowed, the service must error with
FAILED_PRECONDITION
(HTTP 400).
The request message should look like this:
Note: OAS content not yet written.
Additional Guidance
Value uniqueness
Multiple top-level enums within the same package must not share the same values. This is because the C++ protoc code generator flattens top-level enum values into a single namespace.
State enums should live inside the resource definition.
Prefixes
Using a STATE_
prefix on every enum value is unnecessary. State enum values
should not be prefixed with the enum name, except for the default value
STATE_UNSPECIFIED
.
Breaking changes
Even though adding states to an existing states enum can break existing user
code, adding states is not considered a breaking change. Consider a state with
only two values: ACTIVE
and DELETED
. A user may add code that checks
if state == ACTIVE
, and in the else cases simply assumes the resource is
deleted. If the API later adds a new state for another purpose, that code will
break.
API documentation should actively encourage users to code against state enums with the expectation that they may receive new values in the future.
APIs may add new states to an existing State enum when appropriate, and adding a new state is not considered a breaking change.
When to avoid states
Sometimes, a State
enum may not be what is best for your API, particularly in
situations where a state has a very small number of potential values, or when
states are not mutually exclusive.
Consider the example of a state with only ACTIVE
and DELETED
, as discussed
above. In this situation, the API may be better off exposing a
google.protobuf.Timestamp delete_time
, and instructing users to rely on
whether it is set to determine deletion.
Common states
The following is a list of states in common use. APIs should consider prior art when determining state names, and should value local consistency above global consistency in the case of conflicting precedent.
Resting states
“Resting states” are lifecycle states that, absent user action, are expected to remain indefinitely. However, the user can initiate an action to move a resource in a resting state into certain other states (resting or active).
ACCEPTED
ACTIVE
CANCELLED
DELETED
FAILED
SUCCEEDED
SUSPENDED
VERIFIED
Active states
“Active states” are lifecycle states that typically resolve on their own into a single expected resting state.
CREATING
(usually becomesACTIVE
)DELETING
(usually becomesDELETED
)PENDING
(usually becomesRUNNING
)REPAIRING
(usually becomesACTIVE
)RUNNING
(usually becomesSUCCEEDED
)SUSPENDING
(usually becomesSUSPENDED
)
Further reading
- For information on enums generally, see enumerations.