Skip to content

Commit 2498df9

Browse files
authored
Merge pull request #176 from Logofile/main
Documentation update
2 parents f840bb3 + b3cf5bd commit 2498df9

File tree

6 files changed

+196
-13
lines changed

6 files changed

+196
-13
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
+++
2+
title = "1-1-1 Rule"
3+
weight = 105
4+
linkTitle = "1-1-1 Rule"
5+
description = "All proto definitions should have one top-level element and build target per file."
6+
type = "docs"
7+
+++
8+
9+
The 1-1-1 rule has the following elements:
10+
11+
* One `proto_library` rule
12+
* One source `.proto` file
13+
* One top-level entity (message, enum, or extension)
14+
15+
When defining a proto schema, you should have a single message, enum, extension,
16+
service, or group of cyclic dependencies per file. This makes refactoring
17+
easier. Moving files when they're separated is much easier than extracting
18+
messages from a file with other messages. Following this practice also helps to
19+
keep the proto schema files smaller, which enhances maintainability.
20+
21+
One place that modularity of proto schema files is important is when creating
22+
gRPC
23+
definitions. The following set of proto files shows modular structure.
24+
25+
**student_id.proto**
26+
27+
```proto
28+
edition = "2023";
29+
30+
package my.package;
31+
32+
message StudentID {
33+
string value = 1;
34+
}
35+
```
36+
37+
**full_name.proto**
38+
39+
```proto
40+
edition = "2023";
41+
42+
package my.package;
43+
44+
message FullName {
45+
string family_name = 1;
46+
string given_name = 2;
47+
}
48+
```
49+
50+
**student.proto**
51+
52+
```proto
53+
edition = "2023";
54+
55+
package my.package;
56+
57+
import "student_id.proto";
58+
import "full_name.proto";
59+
60+
message Student {
61+
StudentId id = 1;
62+
FullName name = 2;
63+
}
64+
```
65+
66+
**create_student_request.proto**
67+
68+
```proto
69+
edition = "2023";
70+
71+
package my.package;
72+
73+
import "full_name.proto";
74+
75+
message CreateStudentRequest {
76+
FullName name = 1;
77+
}
78+
```
79+
80+
**create_student_response.proto**
81+
82+
```proto
83+
edition = "2023";
84+
85+
package my.package;
86+
87+
import "student.proto";
88+
89+
message CreateStudentResponse {
90+
Student student = 1;
91+
}
92+
```
93+
94+
**get_student_request.proto**
95+
96+
```proto
97+
edition = "2023";
98+
99+
package my.package;
100+
101+
import "student_id.proto";
102+
103+
message GetStudentRequest {
104+
StudentID id = 1;
105+
}
106+
```
107+
108+
**get_student_response.proto**
109+
110+
```proto
111+
edition = "2023";
112+
113+
package my.package;
114+
115+
import "student.proto";
116+
117+
message GetStudentResponse {
118+
Student student = 1;
119+
}
120+
```
121+
122+
**student_service.proto**
123+
124+
```proto
125+
edition = "2023";
126+
127+
package my.package;
128+
129+
import "create_student_request.proto";
130+
import "create_student_response.proto";
131+
import "get_student_request.proto";
132+
import "get_student_response.proto";
133+
134+
service StudentService {
135+
rpc CreateStudent(CreateStudentRequest) returns (CreateStudentResponse);
136+
rpc GetStudent(GetStudentRequest) returns (GetStudentResponse);
137+
}
138+
```
139+
140+
The service definition and each of the message definitions are each in their own
141+
file, and you use includes to give access to the messages from other schema
142+
files.
143+
144+
In this example, `Student`, `StudentID`, and `FullName` are domain types that
145+
are reusable across requests and responses. The top-level request and response
146+
protos are unique to each service+method.
147+
148+
If you later need to add a `middle_name` field to the `FullName` message, you
149+
won't need to update every individual top-level message with that new field.
150+
Likewise, if you need to update `Student` with more information, all the
151+
requests and responses get the update. Further, `StudentID` might update to be a
152+
multi-part ID.
153+
154+
Lastly, having even simple types like `StudentID` wrapped as a message means
155+
that you have created a type that has semantics and consolidated documentation.
156+
For something like `FullName` you'll need to be careful with where this PII gets
157+
logged; this is another advantage of not repeating these fields in multiple
158+
top-level messages. You can tag those fields in one place as sensitive
159+
and exclude them from logging.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
+++
2+
title = "Proto Best Practices"
3+
weight = 90
4+
description = "An overview of best practices topics."
5+
type = "docs"
6+
no_list = "true"
7+
+++
8+
9+
Best practices content for defining and using protos exists in the following
10+
topics:
11+
12+
* [Proto Best Practices](/programming-guides/dos-donts)
13+
* [API Best Practices](/programming-guides/api)
14+
* [1-1-1 Rule](/programming-guides/1-1-1)

content/programming-guides/dos-donts.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,20 @@ when a perfectly suitable common type already exists!
146146

147147
<a id="do-define-widely-used-message-types-in-separate-files"></a>
148148

149-
## **Do** Define Widely-used Message Types in Separate Files {#separate-files}
149+
## **Do** Define Message Types in Separate Files {#separate-files}
150150

151-
If you're defining message types or enums that you hope/fear/expect to be widely
152-
used outside your immediate team, consider putting them in their own file with
153-
no dependencies. Then it's easy for anyone to use those types without
154-
introducing the transitive dependencies in your other proto files.
151+
When defining a proto schema, you should have a single message, enum, extension,
152+
service, or group of cyclic dependencies per file. This makes refactoring
153+
easier. Moving files when they're separated is much easier than extracting
154+
messages from a file with other messages. Following this practice also helps to
155+
keep the proto schema files smaller, which enhances maintainability.
156+
157+
If they will be widely used outside of your project, consider putting them in
158+
their own file with no dependencies. Then it's easy for anyone to use those
159+
types without introducing the transitive dependencies in your other proto files.
160+
161+
For more on this topic, see
162+
[1-1-1 Rule](/programming-guides/1-1-1.md).
155163

156164
<a id="dont-change-the-default-value-of-a-field"></a>
157165

content/programming-guides/style.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ For more service-related guidance, see
126126
[Create Unique Protos per Method](/programming-guides/api#unique-protos)
127127
and
128128
[Don't Include Primitive Types in a Top-level Request or Response Proto](/programming-guides/api#dont-include-primitive-types)
129-
in the API Best Practices topic.
129+
in the API Best Practices topic, and
130+
[Define Messages in Separate Files](/programming-guides/dos-donts.md#separate-files)
131+
in Proto Best Practices.
130132

131133
## Things to Avoid {#avoid}
132134

content/reference/java/java-generated.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The protocol buffer compiler produces Java output when invoked with the
2525
`--java_out=` command-line flag. The parameter to the `--java_out=` option is
2626
the directory where you want the compiler to write your Java output. For each
2727
`.proto` file input, the compiler creates a wrapper `.java` file containing a
28-
Java class which represents the `.proto` file itself.
28+
Java class that represents the `.proto` file itself.
2929

3030
If the `.proto` file contains a line like the following:
3131

@@ -37,12 +37,12 @@ Then the compiler will also create separate `.java` files for each of the
3737
classes/enums which it will generate for each top-level message, enumeration,
3838
and service declared in the `.proto` file.
3939

40-
Otherwise (i.e. when the `java_multiple_files` option is disabled; which is the
40+
Otherwise (when the `java_multiple_files` option is disabled, which is the
4141
default), the aforementioned wrapper class will also be used as an outer class,
4242
and the generated classes/enums for each top-level message, enumeration, and
4343
service declared in the `.proto` file will all be nested within the outer
4444
wrapper class. Thus the compiler will only generate a single `.java` file for
45-
the entire `.proto` file.
45+
the entire `.proto` file, and it will have an extra layer in the package
4646

4747
The wrapper class's name is chosen as follows: If the `.proto` file contains a
4848
line like the following:

content/reference/protobuf/edition-2023-spec.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fields, group fields, oneof fields, or map fields. A field has a label, type and
164164
field number.
165165

166166
```
167-
label = "required" | "optional" | "repeated"
167+
label = [ "repeated" ]
168168
type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
169169
| "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
170170
| "bool" | "string" | "bytes" | messageType | enumType
@@ -173,18 +173,18 @@ fieldNumber = intLit;
173173

174174
### Normal field {#normal_field}
175175

176-
Each field has label, type, name and field number. It may have field options.
176+
Each field has a label, type, name, and field number. It may have field options.
177177

178178
```
179-
field = label type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
179+
field = [label] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
180180
fieldOptions = fieldOption { "," fieldOption }
181181
fieldOption = optionName "=" constant
182182
```
183183

184184
Examples:
185185

186186
```proto
187-
optional foo.bar nested_message = 2;
187+
foo.bar nested_message = 2;
188188
repeated int32 samples = 4 [packed=true];
189189
```
190190

0 commit comments

Comments
 (0)