Skip to content

Commit 6b4e460

Browse files
authored
feat(AIP-180): describe default breaking changes (#1076)
Add specific examples of breaking semantic changes for default values & serialization of default values
1 parent d506b0d commit 6b4e460

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

aip/general/0180.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,93 @@ code, as such changes will be seen as breaking by those users.
139139
whether a proposed change is likely to break users, and an expansive reading of
140140
this guidance could ostensibly prevent _any_ change (which is not the intent).
141141

142+
#### Default values must not change
143+
144+
Default values are the values set by servers for resources when they are not
145+
specified by the client. This section only applies to static default values within
146+
fields on resources and does not apply to dynamic defaults such as the default IP
147+
address of a resource.
148+
149+
Changing the default value is considered breaking and **must not** be done. The
150+
default behavior for a resource is determined by its default values, and this
151+
**must not** change across minor versions.
152+
153+
For example:
154+
155+
```proto
156+
message Book {
157+
string name = 1;
158+
// The genre of the book
159+
// If this is not set when the book is created, the field will be given a value of FICTION.
160+
enum Genre {
161+
UNSPECIFIED = 0;
162+
FICTION = 1;
163+
NONFICTION = 2;
164+
}
165+
}
166+
```
167+
168+
Changing to:
169+
170+
```proto
171+
message Book {
172+
string name = 1;
173+
// The genre of the book
174+
// If this is not set when the book is created, the field will be given a value of NONFICTION.
175+
enum Genre {
176+
UNSPECIFIED = 0;
177+
FICTION = 1;
178+
NONFICTION = 2;
179+
}
180+
}
181+
```
182+
183+
would constitute a breaking change.
184+
185+
#### Serializing defaults
186+
187+
APIs **must not** change the way a field with a default value is serialized. For
188+
example if a field does not appear in the response if the value is equal to the
189+
default, the serialization **must not** change to include the field with the
190+
default. Clients may depend on the presence or absence of a field in a resource
191+
as semantically meaningful, so a change to how serialization is done for absent
192+
values **must not** occur in a minor version.
193+
194+
Consider the following proto, where the default value of `wheels` is `2`:
195+
196+
```proto
197+
// A representation of an automobile
198+
message Automobile {
199+
// The name of the automobile.
200+
string name = 1;
201+
202+
// The number of wheels on the automobile.
203+
// The default value is 2, when no value is sent by the client.
204+
int wheels = 2;
205+
}
206+
```
207+
208+
First the proto serializes to JSON when the value of `wheels` is `2` as follows:
209+
210+
```json
211+
{
212+
"name": "my-car"
213+
}
214+
```
215+
216+
Then, the API service changes the serialization to include `wheel` even if the
217+
value is equal to the default value, `2` as follows:
218+
219+
```json
220+
{
221+
"name": "my-car",
222+
"wheels": 2
223+
}
224+
```
225+
226+
This constitutes a change that is not backwards compatible within a major
227+
version.
228+
142229
## Further reading
143230

144231
- For compatibility around pagination, see [AIP-158][].

0 commit comments

Comments
 (0)