@@ -103,10 +103,10 @@ there is a hard limit on the size of a method
103
103
## ** Do** Include an Unspecified Value in an Enum {#unspecified-enum}
104
104
105
105
Enums should include a default ` FOO_UNSPECIFIED ` value as the first value in the
106
- declaration . When new values
107
- are added to a proto2 enum, old clients will see the field as unset and the
108
- getter will return the default value or the first-declared value if no default
109
- exists . For consistent behavior with [ proto enums] [ proto-enums ] ,
106
+ declaration.
107
+ When new values are added to an enum, old clients will see the field as unset
108
+ and the getter will return the default value or the first-declared value if no
109
+ default exists . For consistent behavior with [ proto enums] [ proto-enums ] ,
110
110
the first declared enum value should be a default ` FOO_UNSPECIFIED ` value and
111
111
should use tag 0. It may be tempting to declare this default as a semantically
112
112
meaningful value but as a general rule, do not, to aid in the evolution of your
@@ -277,6 +277,37 @@ example, see
277
277
You should also avoid using keywords in your file paths, as this can also cause
278
278
problems.
279
279
280
+ ## ** Do** Use Different Messages For RPC APIs and Storage {#separate-types-for-storage}
281
+
282
+ Reusing the same messages for APIs and long-term storage may seem convenient,
283
+ reducing boilerplate and overhead of coversion between messages.
284
+
285
+ However, the needs of long-term storage and live RPC services tend to later
286
+ diverge. Using separate types even if they are largely duplicative initially
287
+ gives freedom to change your storage format without impacting your external
288
+ clients. Layer your code so that modules deal either with client protos, storage
289
+ protos, or translation.
290
+
291
+ There is a cost in maintaining the translation layer, but it quickly pays off
292
+ once you have clients and have to do your first storage changes.
293
+
294
+ ## ** Don't** Use Booleans for Something That Has Two States Now, but Might Have More Later {#bad-bools}
295
+
296
+ If you are using boolean for a field, make sure that the field is indeed
297
+ describing just two possible states (for all time, not just now and the near
298
+ future). The future flexibility of using an enum is often worth it, even if it
299
+ only has two values when it is first introduced.
300
+
301
+ ```
302
+ message Photo {
303
+ // Bad: True if it's a GIF.
304
+ optional bool gif;
305
+
306
+ // Good: File format of the referenced photo (for example, GIF, WebP, PNG).
307
+ optional PhotoType type;
308
+ }
309
+ ```
310
+
280
311
## ** Do** Use java_outer_classname {#java-outer-classname}
281
312
282
313
Every proto schema definition file should set option ` java_outer_classname ` to
@@ -286,11 +317,3 @@ the file `student_record_request.proto` should set:
286
317
``` java
287
318
option java_outer_classname = " StudentRecordRequestProto" ;
288
319
```
289
-
290
- ## Appendix {#appendix}
291
-
292
- ### API Best Practices {#api-best-practices}
293
-
294
- This document lists only changes that are extremely likely to cause breakage.
295
- For higher-level guidance on how to craft proto APIs that grow gracefully see
296
- [ API Best Practices] ( /best-practices/api ) .
0 commit comments