...
1syntax = "proto3";
2option go_package = "examplepb";
3package grpc.gateway.examples.internal.examplepb;
4
5import "google/api/annotations.proto";
6import "google/protobuf/field_mask.proto";
7import "google/protobuf/empty.proto";
8import "google/protobuf/duration.proto";
9import "google/protobuf/wrappers.proto";
10import "examples/internal/proto/pathenum/path_enum.proto";
11import "examples/internal/proto/sub/message.proto";
12import "examples/internal/proto/sub2/message.proto";
13import "google/protobuf/timestamp.proto";
14import "protoc-gen-swagger/options/annotations.proto";
15
16option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
17 info: {
18 title: "A Bit of Everything";
19 version: "1.0";
20 contact: {
21 name: "gRPC-Gateway project";
22 url: "https://github.com/grpc-ecosystem/grpc-gateway";
23 email: "none@example.com";
24 };
25 license: {
26 name: "BSD 3-Clause License";
27 url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt";
28 };
29 extensions: {
30 key: "x-something-something";
31 value {
32 string_value: "yadda";
33 }
34 }
35 };
36 // Overwriting host entry breaks tests, so this is not done here.
37 external_docs: {
38 url: "https://github.com/grpc-ecosystem/grpc-gateway";
39 description: "More about gRPC-Gateway";
40 }
41 schemes: HTTP;
42 schemes: HTTPS;
43 schemes: WSS;
44 consumes: "application/json";
45 consumes: "application/x-foo-mime";
46 produces: "application/json";
47 produces: "application/x-foo-mime";
48 security_definitions: {
49 security: {
50 key: "BasicAuth";
51 value: {
52 type: TYPE_BASIC;
53 }
54 }
55 security: {
56 key: "ApiKeyAuth";
57 value: {
58 type: TYPE_API_KEY;
59 in: IN_HEADER;
60 name: "X-API-Key";
61 extensions: {
62 key: "x-amazon-apigateway-authtype";
63 value {
64 string_value: "oauth2";
65 }
66 }
67 extensions: {
68 key: "x-amazon-apigateway-authorizer";
69 value {
70 struct_value {
71 fields {
72 key: "type";
73 value {
74 string_value: "token";
75 }
76 }
77 fields {
78 key: "authorizerResultTtlInSeconds";
79 value {
80 number_value: 60;
81 }
82 }
83 }
84 }
85 }
86 }
87 }
88 security: {
89 key: "OAuth2";
90 value: {
91 type: TYPE_OAUTH2;
92 flow: FLOW_ACCESS_CODE;
93 authorization_url: "https://example.com/oauth/authorize";
94 token_url: "https://example.com/oauth/token";
95 scopes: {
96 scope: {
97 key: "read";
98 value: "Grants read access";
99 }
100 scope: {
101 key: "write";
102 value: "Grants write access";
103 }
104 scope: {
105 key: "admin";
106 value: "Grants read and write access to administrative information";
107 }
108 }
109 }
110 }
111 }
112 security: {
113 security_requirement: {
114 key: "BasicAuth";
115 value: {};
116 }
117 security_requirement: {
118 key: "ApiKeyAuth";
119 value: {};
120 }
121 }
122 security: {
123 security_requirement: {
124 key: "OAuth2";
125 value: {
126 scope: "read";
127 scope: "write";
128 }
129 }
130 security_requirement: {
131 key: "ApiKeyAuth";
132 value: {};
133 }
134 }
135 responses: {
136 key: "403";
137 value: {
138 description: "Returned when the user does not have permission to access the resource.";
139 }
140 }
141 responses: {
142 key: "404";
143 value: {
144 description: "Returned when the resource does not exist.";
145 schema: {
146 json_schema: {
147 type: STRING;
148 }
149 }
150 }
151 }
152 responses: {
153 key: "418";
154 value: {
155 description: "I'm a teapot.";
156 schema: {
157 json_schema: {
158 ref: ".grpc.gateway.examples.internal.examplepb.NumericEnum";
159 }
160 }
161 }
162 }
163 responses: {
164 key: "500";
165 value: {
166 description: "Server error";
167 headers: {
168 key: "X-Correlation-Id"
169 value: {
170 description: "Unique event identifier for server requests"
171 type: "string"
172 format: "uuid"
173 default: "\"2438ac3c-37eb-4902-adef-ed16b4431030\""
174 pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
175 }
176 };
177 schema: {
178 json_schema: {
179 ref: ".grpc.gateway.examples.internal.examplepb.ErrorResponse";
180 }
181 }
182 }
183 }
184 extensions: {
185 key: "x-grpc-gateway-foo";
186 value {
187 string_value: "bar";
188 }
189 }
190 extensions: {
191 key: "x-grpc-gateway-baz-list";
192 value {
193 list_value: {
194 values: {
195 string_value: "one";
196 }
197 values: {
198 bool_value: true;
199 }
200 }
201 }
202 }
203};
204
205message ErrorResponse{
206 string correlationId = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
207 pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$",
208 title: "x-correlation-id",
209 description: "Unique event identifier for server requests",
210 format: "uuid",
211 example: "\"2438ac3c-37eb-4902-adef-ed16b4431030\""
212 }];
213 ErrorObject error = 2;
214}
215
216message ErrorObject{
217 int32 code = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
218 pattern: "^[0-9]$",
219 title: "code",
220 description: "Response code",
221 format: "integer"
222 }];
223 string message = 2 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {
224 pattern: "^[a-zA-Z0-9]{1, 32}$",
225 title: "message",
226 description: "Response message"
227 }];
228}
229
230
231// Intentionally complicated message type to cover many features of Protobuf.
232message ABitOfEverything {
233 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
234 json_schema: {
235 title: "A bit of everything"
236 description: "Intentionaly complicated message type to cover many features of Protobuf."
237 required: ["uuid", "int64_value", "double_value"]
238 }
239 external_docs: {
240 url: "https://github.com/grpc-ecosystem/grpc-gateway";
241 description: "Find out more about ABitOfEverything";
242 }
243 example_string: "{\"uuid\": \"0cf361e1-4b44-483d-a159-54dabdf7e814\"}"
244 };
245
246 // Nested is nested type.
247 message Nested {
248 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
249 example_string: "{\"ok\": \"TRUE\"}"
250 };
251 // name is nested field.
252 string name = 1;
253 uint32 amount = 2;
254 // DeepEnum is one or zero.
255 enum DeepEnum {
256 // FALSE is false.
257 FALSE = 0;
258 // TRUE is true.
259 TRUE = 1;
260 }
261
262 // DeepEnum comment.
263 DeepEnum ok = 3 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {description: "DeepEnum description."}];
264 }
265 Nested single_nested = 25;
266
267 string uuid = 1 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {pattern: "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", min_length: 1}];
268 repeated Nested nested = 2;
269 float float_value = 3 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {description: "Float value field", default: "0.2", required: ['float_value']}];
270 double double_value = 4;
271 int64 int64_value = 5;
272 uint64 uint64_value = 6;
273 int32 int32_value = 7;
274 fixed64 fixed64_value = 8;
275 fixed32 fixed32_value = 9;
276 bool bool_value = 10;
277 string string_value = 11;
278 bytes bytes_value = 29;
279 uint32 uint32_value = 13;
280 NumericEnum enum_value = 14;
281 pathenum.PathEnum path_enum_value = 30;
282 pathenum.MessagePathEnum.NestedPathEnum nested_path_enum_value = 31;
283 sfixed32 sfixed32_value = 15;
284 sfixed64 sfixed64_value = 16;
285 sint32 sint32_value = 17;
286 sint64 sint64_value = 18;
287 repeated string repeated_string_value = 19;
288 oneof oneof_value {
289 google.protobuf.Empty oneof_empty = 20;
290 string oneof_string = 21;
291 }
292
293 map<string, NumericEnum> map_value = 22;
294 map<string, string> mapped_string_value = 23;
295 map<string, Nested> mapped_nested_value = 24;
296
297 string nonConventionalNameValue = 26;
298
299 google.protobuf.Timestamp timestamp_value = 27;
300
301 // repeated enum value. it is comma-separated in query
302 repeated NumericEnum repeated_enum_value = 28;
303
304 // repeated numeric enum comment (This comment is overridden by the field annotation)
305 repeated NumericEnum repeated_enum_annotation = 32 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {title: "Repeated numeric enum title", description: "Repeated numeric enum description."}];
306
307 // numeric enum comment (This comment is overridden by the field annotation)
308 NumericEnum enum_value_annotation = 33 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {title: "Numeric enum title", description: "Numeric enum description."}];
309
310 // repeated string comment (This comment is overridden by the field annotation)
311 repeated string repeated_string_annotation = 34 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {title: "Repeated string title", description: "Repeated string description."}];
312
313 // repeated nested object comment (This comment is overridden by the field annotation)
314 repeated Nested repeated_nested_annotation = 35 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {title: "Repeated nested object title", description: "Repeated nested object description."}];
315
316 // nested object comments (This comment is overridden by the field annotation)
317 Nested nested_annotation = 36 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {title: "Nested object title", description: "Nested object description."}];
318
319 int64 int64_override_type = 37 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = {type: INTEGER}];
320}
321
322// ABitOfEverythingRepeated is used to validate repeated path parameter functionality
323message ABitOfEverythingRepeated {
324 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
325 example_string: "{\"path_repeated_bool_value\": [true, true, false, true], \"path_repeated_int32_value\": [1, 2, 3]}"
326 };
327
328 // repeated values. they are comma-separated in path
329 repeated float path_repeated_float_value = 1;
330 repeated double path_repeated_double_value = 2;
331 repeated int64 path_repeated_int64_value = 3;
332 repeated uint64 path_repeated_uint64_value = 4;
333 repeated int32 path_repeated_int32_value = 5;
334 repeated fixed64 path_repeated_fixed64_value = 6;
335 repeated fixed32 path_repeated_fixed32_value = 7;
336 repeated bool path_repeated_bool_value = 8;
337 repeated string path_repeated_string_value = 9;
338 repeated bytes path_repeated_bytes_value = 10;
339 repeated uint32 path_repeated_uint32_value = 11;
340 repeated NumericEnum path_repeated_enum_value = 12;
341 repeated sfixed32 path_repeated_sfixed32_value = 13;
342 repeated sfixed64 path_repeated_sfixed64_value = 14;
343 repeated sint32 path_repeated_sint32_value = 15;
344 repeated sint64 path_repeated_sint64_value = 16;
345}
346
347message Body {
348 string name = 1;
349}
350
351message MessageWithBody {
352 string id = 1;
353 Body data = 2;
354}
355
356
357// NumericEnum is one or zero.
358enum NumericEnum {
359 // ZERO means 0
360 ZERO = 0;
361 // ONE means 1
362 ONE = 1;
363}
364
365// UpdateV2Request request for update includes the message and the update mask
366message UpdateV2Request {
367 ABitOfEverything abe = 1;
368 google.protobuf.FieldMask update_mask = 2;
369}
370
371// An example resource type from AIP-123 used to test the behavior described in
372// the CreateBookRequest message.
373//
374// See: https://google.aip.dev/123
375message Book {
376 // The resource name of the book.
377 //
378 // Format: `publishers/{publisher}/books/{book}`
379 //
380 // Example: `publishers/1257894000000000000/books/my-book`
381 string name = 1;
382
383 // Output only. The book's ID.
384 string id = 2;
385
386 // Output only. Creation time of the book.
387 google.protobuf.Timestamp create_time = 3;
388}
389
390// A standard Create message from AIP-133 with a user-specified ID.
391// The user-specified ID (the `book_id` field in this example) must become a
392// query parameter in the OpenAPI spec.
393//
394// See: https://google.aip.dev/133#user-specified-ids
395message CreateBookRequest {
396 // The publisher in which to create the book.
397 //
398 // Format: `publishers/{publisher}`
399 //
400 // Example: `publishers/1257894000000000000`
401 string parent = 1;
402
403 // The book to create.
404 Book book = 2;
405
406 // The ID to use for the book.
407 //
408 // This must start with an alphanumeric character.
409 string book_id = 3;
410}
411
412// ABitOfEverything service is used to validate that APIs with complicated
413// proto messages and URL templates are still processed correctly.
414service ABitOfEverythingService {
415
416 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_tag) = {
417 description: "ABitOfEverythingService description -- which should not be used in place of the documentation comment!"
418 external_docs: {
419 url: "https://github.com/grpc-ecosystem/grpc-gateway";
420 description: "Find out more about EchoService";
421 }
422 };
423
424 // Create a new ABitOfEverything
425 //
426 // This API creates a new ABitOfEverything
427 rpc Create(ABitOfEverything) returns (ABitOfEverything) {
428 option (google.api.http) = {
429 post: "/v1/example/a_bit_of_everything/{float_value}/{double_value}/{int64_value}/separator/{uint64_value}/{int32_value}/{fixed64_value}/{fixed32_value}/{bool_value}/{string_value=strprefix/*}/{uint32_value}/{sfixed32_value}/{sfixed64_value}/{sint32_value}/{sint64_value}/{nonConventionalNameValue}/{enum_value}/{path_enum_value}/{nested_path_enum_value}/{enum_value_annotation}"
430 };
431 }
432 rpc CreateBody(ABitOfEverything) returns (ABitOfEverything) {
433 option (google.api.http) = {
434 post: "/v1/example/a_bit_of_everything"
435 body: "*"
436 };
437 }
438 // Create a book.
439 rpc CreateBook(CreateBookRequest) returns (Book) {
440 option (google.api.http) = {
441 post: "/v1/{parent=publishers/*}/books"
442 body: "book"
443 };
444 }
445 rpc Lookup(sub2.IdMessage) returns (ABitOfEverything) {
446 option (google.api.http) = {
447 get: "/v1/example/a_bit_of_everything/{uuid}"
448 };
449 }
450 rpc Update(ABitOfEverything) returns (google.protobuf.Empty) {
451 option (google.api.http) = {
452 put: "/v1/example/a_bit_of_everything/{uuid}"
453 body: "*"
454 };
455 }
456 rpc UpdateV2(UpdateV2Request) returns (google.protobuf.Empty) {
457 option (google.api.http) = {
458 put: "/v2/example/a_bit_of_everything/{abe.uuid}"
459 body: "abe"
460 additional_bindings: [
461 {
462 patch: "/v2/example/a_bit_of_everything/{abe.uuid}"
463 body: "abe"
464 },
465 {
466 patch: "/v2a/example/a_bit_of_everything/{abe.uuid}"
467 body: "*"
468 }
469 ]
470 };
471 }
472
473 rpc Delete(sub2.IdMessage) returns (google.protobuf.Empty) {
474 option (google.api.http) = {
475 delete: "/v1/example/a_bit_of_everything/{uuid}"
476 };
477 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
478 security: {
479 security_requirement: {
480 key: "ApiKeyAuth";
481 value: {}
482 }
483 security_requirement: {
484 key: "OAuth2";
485 value: {
486 scope: "read";
487 scope: "write";
488 }
489 }
490 }
491 extensions: {
492 key: "x-irreversible";
493 value {
494 bool_value: true;
495 }
496 }
497 };
498 }
499 rpc GetQuery(ABitOfEverything) returns (google.protobuf.Empty) {
500 option (google.api.http) = {
501 get: "/v1/example/a_bit_of_everything/query/{uuid}"
502 };
503 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
504 deprecated: true // For testing purposes.
505 external_docs: {
506 url: "https://github.com/grpc-ecosystem/grpc-gateway";
507 description: "Find out more about GetQuery";
508 }
509 security: {
510 }
511 };
512 }
513 rpc GetRepeatedQuery(ABitOfEverythingRepeated) returns (ABitOfEverythingRepeated) {
514 option (google.api.http) = {
515 get: "/v1/example/a_bit_of_everything_repeated/{path_repeated_float_value}/{path_repeated_double_value}/{path_repeated_int64_value}/{path_repeated_uint64_value}/{path_repeated_int32_value}/{path_repeated_fixed64_value}/{path_repeated_fixed32_value}/{path_repeated_bool_value}/{path_repeated_string_value}/{path_repeated_bytes_value}/{path_repeated_uint32_value}/{path_repeated_enum_value}/{path_repeated_sfixed32_value}/{path_repeated_sfixed64_value}/{path_repeated_sint32_value}/{path_repeated_sint64_value}"
516 };
517 }
518 // Echo allows posting a StringMessage value.
519 //
520 // It also exposes multiple bindings.
521 //
522 // This makes it useful when validating that the OpenAPI v2 API
523 // description exposes documentation correctly on all paths
524 // defined as additional_bindings in the proto.
525 rpc Echo(grpc.gateway.examples.internal.sub.StringMessage) returns (grpc.gateway.examples.internal.sub.StringMessage) {
526 option (google.api.http) = {
527 get: "/v1/example/a_bit_of_everything/echo/{value}"
528 additional_bindings {
529 post: "/v2/example/echo"
530 body: "value"
531 }
532 additional_bindings {
533 get: "/v2/example/echo"
534 }
535 };
536 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
537 description: "Description Echo";
538 summary: "Summary: Echo rpc";
539 tags: "echo rpc";
540 external_docs: {
541 url: "https://github.com/grpc-ecosystem/grpc-gateway";
542 description: "Find out more Echo";
543 }
544 responses: {
545 key: "200"
546 value: {
547 examples: {
548 key: "application/json"
549 value: '{"value": "the input value"}'
550 }
551 }
552 }
553 responses: {
554 key: "503";
555 value: {
556 description: "Returned when the resource is temporarily unavailable.";
557 extensions: {
558 key: "x-number";
559 value {
560 number_value: 100;
561 }
562 }
563 }
564 }
565 responses: {
566 // Overwrites global definition.
567 key: "404";
568 value: {
569 description: "Returned when the resource does not exist.";
570 schema: {
571 json_schema: {
572 type: INTEGER;
573 }
574 }
575 }
576 }
577 };
578 }
579 rpc DeepPathEcho(ABitOfEverything) returns (ABitOfEverything) {
580 option (google.api.http) = {
581 post: "/v1/example/a_bit_of_everything/{single_nested.name}"
582 body: "*"
583 };
584 }
585 rpc NoBindings(google.protobuf.Duration) returns (google.protobuf.Empty) {}
586 rpc Timeout(google.protobuf.Empty) returns (google.protobuf.Empty) {
587 option (google.api.http) = {
588 get: "/v2/example/timeout",
589 };
590 }
591 rpc ErrorWithDetails(google.protobuf.Empty) returns (google.protobuf.Empty) {
592 option (google.api.http) = {
593 get: "/v2/example/errorwithdetails",
594 };
595 }
596 rpc GetMessageWithBody(MessageWithBody) returns (google.protobuf.Empty) {
597 option (google.api.http) = {
598 post: "/v2/example/withbody/{id}",
599 body: "data"
600 };
601 }
602 rpc PostWithEmptyBody(Body) returns (google.protobuf.Empty) {
603 option (google.api.http) = {
604 post: "/v2/example/postwithemptybody/{name}",
605 body: "*"
606 };
607 }
608 rpc CheckGetQueryParams(ABitOfEverything) returns (ABitOfEverything) {
609 option (google.api.http) = {
610 get: "/v1/example/a_bit_of_everything/params/get/{single_nested.name}"
611 };
612 }
613 rpc CheckNestedEnumGetQueryParams(ABitOfEverything) returns (ABitOfEverything) {
614 option (google.api.http) = {
615 get: "/v1/example/a_bit_of_everything/params/get/nested_enum/{single_nested.ok}"
616 };
617 }
618 rpc CheckPostQueryParams(ABitOfEverything) returns (ABitOfEverything) {
619 option (google.api.http) = {
620 post: "/v1/example/a_bit_of_everything/params/post/{string_value}"
621 body: "single_nested"
622 };
623 }
624 rpc OverwriteResponseContentType(google.protobuf.Empty) returns (google.protobuf.StringValue) {
625 option (google.api.http) = {
626 get: "/v2/example/overwriteresponsecontenttype"
627 };
628 option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
629 produces: "application/text"
630 };
631 }
632 rpc CheckExternalPathEnum(pathenum.MessageWithPathEnum) returns (google.protobuf.Empty) {
633 option (google.api.http) = {
634 get: "/v2/{value}:check"
635 };
636 }
637 rpc CheckExternalNestedPathEnum(pathenum.MessageWithNestedPathEnum) returns (google.protobuf.Empty) {
638 option (google.api.http) = {
639 get: "/v2/{value}:check"
640 };
641 }
642}
643
644// camelCase and lowercase service names are valid but not recommended (use TitleCase instead)
645service camelCaseServiceName {
646 rpc Empty(google.protobuf.Empty) returns (google.protobuf.Empty) {
647 option (google.api.http) = {
648 get: "/v2/example/empty",
649 };
650 }
651}
652service AnotherServiceWithNoBindings {
653 rpc NoBindings(google.protobuf.Empty) returns (google.protobuf.Empty) {}
654}
View as plain text