Skip to content

Commit 65579cc

Browse files
Luke Sneeringermkistler
authored andcommitted
feat: AIP-128 – Declarative-friendly interfaces
1 parent 5748816 commit 65579cc

4 files changed

Lines changed: 172 additions & 0 deletions

File tree

aip/general/0128/aip.md.j2

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Declarative-friendly interfaces
2+
3+
Many services need to interact with common DevOps tools, particularly those
4+
that create and manage network-addressible resources (such as virtual machines,
5+
load balancers, database instances, and so on). These tools revolve around the
6+
principle of "configuration as code": the user specifies the complete intended
7+
landscape, and tooling is responsible for making whatever changes are necessary
8+
to achieve the user's specification.
9+
10+
These tools are **declarative**: rather than specifying specific _actions_ to
11+
take, they specify the desired _outcome_, with the actions being derived based
12+
on the differences between the current landscape and the intended one.
13+
14+
Furthermore, there are numerous popular DevOps tools, with more being
15+
introduced each year. Integrating hundreds of resource types with multiple
16+
tools requires strong consistency, so that integration can be automated.
17+
18+
## Guidance
19+
20+
Services **should** clearly delineate between "control plane" operations and
21+
"data plane" operations, ideally through the use of distinct services with
22+
their own interface definition documents.
23+
24+
- Control plane operations are responsible for managing the _lifecycle_ of
25+
resources.
26+
- Data plane operations are responsible for managing the _content_ of
27+
resources.
28+
29+
The same resource **may** have both control plane operations and data plane
30+
operations associated with it. For example, a database API would have
31+
operations to create or delete database tables (control plane) as well as
32+
operations to write and read rows to that table (data plane).
33+
34+
### Resources
35+
36+
Resources that are declarative-friendly **must** use only strongly-consistent
37+
standard methods for managing resource lifecycle, which allows tools to support
38+
these resources generically, as well as conforming to other
39+
declarative-friendly guidance (see [further reading](#further-reading)).
40+
41+
Declarative-friendly resources **should** designate that they follow the
42+
declarative-friendly style:
43+
44+
{% tab proto %}
45+
46+
{% sample 'declarative_friendly.proto', 'message Book' %}
47+
48+
{% tab oas %}
49+
50+
{% sample 'declarative_friendly.oas.yaml', 'schema' %}
51+
52+
{% endtabs %}
53+
54+
### Annotations
55+
56+
Declarative-friendly resources **must** include a `annotations` field to allow
57+
clients to store small amounts of arbitrary data:
58+
59+
```typescript
60+
// A representation of a single book.
61+
interface Book {
62+
// The name of the book.
63+
// Format: publishers/{publisher}/books/{book}
64+
name: string;
65+
66+
// Other fields...
67+
68+
// A dictionary of key-value pairs.
69+
// This has no effect on the service's behavior, but clients may use it
70+
// to persistently store small amounts of information related to this
71+
// resource.
72+
annotations: { [key: string]: string };
73+
}
74+
```
75+
76+
The `annotations` field **must** use the [Kubernetes limits][] to maintain wire
77+
compatibility, and **should** require dot-namespaced annotation keys to prevent
78+
tools from trampling over one another.
79+
80+
**Note:** Annotations are distinct from various forms of labels. Labels can be
81+
used by server-side policies, such as IAM conditions. Annotations exist to
82+
allow client tools to store their own state information without requiring a
83+
database.
84+
85+
<!-- prettier-ignore -->
86+
[kubernetes limits]: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
87+
88+
### Reconciliation
89+
90+
If a resource takes time (more than a few seconds) for updates to be realized,
91+
the resource **should** include a `bool reconciling` field to disclose that
92+
changes are in flight. This field **must** be output only.
93+
94+
A resource **must** set the `reconciling` field to `true` if the current state
95+
of the resource does not match the user's intended state, and the system is
96+
working to reconcile them. This is regardless of whether the root cause of
97+
going into reconciliation was user or system action.
98+
99+
**Note:** Services responding to a `GET` request **must** return the resource's
100+
current state (not the intended state).
101+
102+
## Further reading
103+
104+
A significant amount of guidance is more strict for declarative-friendly
105+
interfaces, due to the focus on automation on top of these resources. This list
106+
is a comprehensive reference to declarative-friendly guidance in other AIPs:
107+
108+
- Resources **must** use user-settable resource IDs: see AIP-133.
109+
- Resources **must** permit "create or update": see AIP-134.
110+
- Resources **should** permit "delete if existing": see AIP-135.
111+
- Resources **should not** employ custom methods: see AIP-136.
112+
- Resources **must** use the `Update` method for repeated fields: see AIP-144.
113+
- Resources **must** include certain standard fields: see AIP-148.
114+
- Resources **must** have an `etag` field: see AIP-154.
115+
- Resources **must** provide change validation: see AIP-163.
116+
- Resources **should** support soft delete: see AIP-164.

aip/general/0128/aip.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
id: 128
3+
state: approved
4+
created: 2020-10-06
5+
placement:
6+
category: resource-design
7+
order: 65
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
openapi: 3.0.3
3+
info:
4+
title: Library
5+
version: 1.0.0
6+
components:
7+
schema:
8+
Book:
9+
description: A representation of a single book.
10+
x-declarative-friendly: true
11+
properties:
12+
name:
13+
type: string
14+
description: |
15+
The name of the book.
16+
Format: publishers/{publisher}/books/{book}
17+
# Additional fields...
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
syntax = "proto3";
16+
17+
import "google/api/resource.proto";
18+
19+
// A representation of a book.
20+
message Book {
21+
option (google.api.resource) = {
22+
type: "library.googleapis.com/Book"
23+
pattern: "publishers/{publisher}/books/{book}"
24+
style: DECLARATIVE_FRIENDLY
25+
};
26+
27+
// The name of the book.
28+
// Format: publishers/{publisher}/books/{book}
29+
string name = 1;
30+
31+
// Other fields...
32+
}

0 commit comments

Comments
 (0)