Array fields
Within API, methods that operate on schemas containing arrays require consideration on the strategies for updating elements within the list.
For larger arrays of resources, consider pagination.
Guidance
Resources may use array fields where appropriate.
Note: OAS guidance not yet written
- Array fields should use a plural field name.
- If the English singular and plural words are identical (“moose”, “info”), the dictionary word must be used rather than attempting to coin a new plural form.
- Array fields should have an enforced upper bound that will not cause a
single resource payload to become too large. A good rule of thumb is 100
elements.
- If an array data can not be bounded (in other words, if there is a chance that the array will be too large to be reasonably returned in a single request), the API should use a sub-resource instead.
Scalars and structs
Array fields should use a scalar type (such as string
) if they are
certain that additional data will not be needed in the future, as using a
struct type adds significant cognitive overhead and leads to more complicated
code.
However, if additional data is likely to be needed in the future, array fields should use a struct instead of a scalar proactively, to avoid parallel array fields.
Update strategies
A resource may use one of two strategies to enable updating a array field:
direct update using the standard Update
method, or custom Add
and Remove
methods.
A standard Update
method has one key limitation: the user is only able to
update the entire array. This means that the user is required to read the
resource, make modifications to the array field value as needed, and send it
back. This is fine for many situations, particularly when the array field is
expected to have a small size (fewer than 10 or so) and race conditions are not
an issue, or can be guarded against with ETags.
If atomic modifications are required, and if the array is functionally a set
(meaning that order does not matter, duplicate values are not meaningful, and
non-comparable values such as null
or NaN
are not used), the API should
define custom methods using the verbs Add
and Remove
:
-
The data being added or removed should be a primitive (usually a
string
).- For more complex data structures with a primary key, the API should use
a map with the
Update
method instead.
- For more complex data structures with a primary key, the API should use
a map with the
-
The RPC’s name must begin with the word
Add
orRemove
. The remainder of the RPC name should be the singular form of the field being added. -
The response should be the resource itself, and should fully-populate the resource structure.
-
The HTTP method must be
POST
, as usual for custom methods. -
The HTTP URI must end with
:add*
or:remove*
, where*
is the camel-case singular name of the field being added or removed. -
The request field receiving the resource name should map to the URI path.
- The HTTP variable should be the name of the resource (such as
book
) rather thanname
orparent
. - That variable should be the only variable in the URI path.
- The HTTP variable should be the name of the resource (such as
-
The body clause in the
google.api.http
annotation should be"*"
. -
If the data being added in an
Add
operation is already present, the method should accept the request and make no changes (no-op), but may error withALREADY_EXISTS
if appropriate. -
If the data being removed in a
Remove
operation is not present, the method should accept the request and make no changes (no-op), but may error withNOT_FOUND
if appropriate.
-
The data being added or removed should be a primitive (usually a
string
).- For more complex data structures with a primary key, the API should use
a map with the
Update
method instead.
- For more complex data structures with a primary key, the API should use
a map with the
-
The
operationId
must begin with the wordadd
orremove
. The remainder of theoperationId
should be the singular form of the field being added. -
The response should be the resource itself, and should fully-populate the resource structure.
-
The HTTP method must be
POST
, as usual for custom methods. -
The HTTP URI must end with
:add*
or:remove*
, where*
is the camel-case singular name of the field being added or removed. -
If the data being added in an
Add
operation is already present, the method should accept the request and make no changes (no-op), but may error with409 Conflict
if appropriate. -
If the data being removed in a
Remove
operation is not present, the method should accept the request and make no changes (no-op), but may error with404 Not Found
if appropriate.
Request Structure
-
A resource field must be included. It should be the name of the resource (such as
book
) rather thanname
orparent
.- The field should be annotated as required.
- If the field represents the name of another resource, it should identify the resource type that it references.
-
A field for the value being added or removed must be included. It should be the singular name of the field.
- The field should be annotated as required.
-
The request message must not contain any other required fields, and should not contain other optional fields except those described in this or another AEP.
- A field for the value being added or removed must be included. It
should be the singular name of the field.
-
The field should be designated as required.
-