1-
21package api
32
43import (
5-
64 "fmt"
75 "io"
86)
97
10-
11-
128type FieldBehavior string
139
1410const (
@@ -27,52 +23,233 @@ func (f *FieldBehavior) String() string {
2723 return string (* f )
2824}
2925
30-
31-
32-
33-
26+ // A custom pattern is used for defining custom HTTP verb.
3427type CustomHttpPattern struct {
35-
3628 Kind * string `json:"kind"`
37-
3829 Path * string `json:"path"`
39-
4030}
4131
42-
43-
32+ // Defines the HTTP configuration for an API service. It contains a list of
33+ // [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
34+ // to one or more HTTP REST API methods.
4435type Http struct {
45-
4636 Rules []HttpRule `json:"rules"`
47-
4837 FullyDecodeReservedExpansion * bool `json:"fullyDecodeReservedExpansion"`
49-
5038}
5139
52-
53-
40+ // # gRPC Transcoding
41+ //
42+ // gRPC Transcoding is a feature for mapping between a gRPC method and one or
43+ // more HTTP REST endpoints. It allows developers to build a single API service
44+ // that supports both gRPC APIs and REST APIs. Many systems, including [Google
45+ // APIs], [Cloud Endpoints], [gRPC Gateway], and [Envoy] proxy support this
46+ // feature and use it for large scale production services.
47+ //
48+ // `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies
49+ // how different portions of the gRPC request message are mapped to the URL
50+ // path, URL query parameters, and HTTP request body. It also controls how the
51+ // gRPC response message is mapped to the HTTP response body. `HttpRule` is
52+ // typically specified as an `google.api.http` annotation on the gRPC method.
53+ //
54+ // Each mapping specifies a URL path template and an HTTP method. The path
55+ // template may refer to one or more fields in the gRPC request message, as long
56+ // as each field is a non-repeated field with a primitive (non-message) type.
57+ // The path template controls how fields of the request message are mapped to
58+ // the URL path.
59+ //
60+ // Example:
61+ //
62+ // service Messaging { rpc GetMessage(GetMessageRequest) returns (Message) {
63+ // option (google.api.http) = { get: "/v1/{name=messages/*}" }; } } message
64+ // GetMessageRequest { string name = 1; // Mapped to URL path. } message Message
65+ // { string text = 1; // The resource content. }
66+ //
67+ // This enables an HTTP REST to gRPC mapping as below:
68+ //
69+ // HTTP | gRPC -----|----- `GET /v1/messages/123456` | `GetMessage(name:
70+ // "messages/123456")`
71+ //
72+ // Any fields in the request message which are not bound by the path template
73+ // automatically become HTTP query parameters if there is no HTTP request body.
74+ // For example:
75+ //
76+ // service Messaging { rpc GetMessage(GetMessageRequest) returns (Message) {
77+ // option (google.api.http) = { get:"/v1/messages/{message_id}" }; } } message
78+ // GetMessageRequest { message SubMessage { string subfield = 1; } string
79+ // message_id = 1; // Mapped to URL path. int64 revision = 2; // Mapped to URL
80+ // query parameter `revision`. SubMessage sub = 3; // Mapped to URL query
81+ // parameter `sub.subfield`. }
82+ //
83+ // This enables a HTTP JSON to RPC mapping as below:
84+ //
85+ // HTTP | gRPC -----|----- `GET /v1/messages/123456?revision=2&sub.subfield=foo`
86+ // | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield:
87+ // "foo"))`
88+ //
89+ // Note that fields which are mapped to URL query parameters must have a
90+ // primitive type or a repeated primitive type or a non-repeated message type.
91+ // In the case of a repeated type, the parameter can be repeated in the URL as
92+ // `...?param=A¶m=B`. In the case of a message type, each field of the
93+ // message is mapped to a separate parameter, such as
94+ // `...?foo.a=A&foo.b=B&foo.c=C`.
95+ //
96+ // For HTTP methods that allow a request body, the `body` field specifies the
97+ // mapping. Consider a REST update method on the message resource collection:
98+ //
99+ // service Messaging { rpc UpdateMessage(UpdateMessageRequest) returns (Message)
100+ // { option (google.api.http) = { patch: "/v1/messages/{message_id}" body:
101+ // "message" }; } } message UpdateMessageRequest { string message_id = 1; //
102+ // mapped to the URL Message message = 2; // mapped to the body }
103+ //
104+ // The following HTTP JSON to RPC mapping is enabled, where the representation
105+ // of the JSON in the request body is determined by protos JSON encoding:
106+ //
107+ // HTTP | gRPC -----|----- `PATCH /v1/messages/123456 { "text": "Hi!" }` |
108+ // `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
109+ //
110+ // The special name `*` can be used in the body mapping to define that every
111+ // field not bound by the path template should be mapped to the request body.
112+ // This enables the following alternative definition of the update method:
113+ //
114+ // service Messaging { rpc UpdateMessage(Message) returns (Message) { option
115+ // (google.api.http) = { patch: "/v1/messages/{message_id}" body: "*" }; } }
116+ // message Message { string message_id = 1; string text = 2; }
117+ //
118+ // The following HTTP JSON to RPC mapping is enabled:
119+ //
120+ // HTTP | gRPC -----|----- `PATCH /v1/messages/123456 { "text": "Hi!" }` |
121+ // `UpdateMessage(message_id: "123456" text: "Hi!")`
122+ //
123+ // Note that when using `*` in the body mapping, it is not possible to have HTTP
124+ // parameters, as all fields not bound by the path end in the body. This makes
125+ // this option more rarely used in practice when defining REST APIs. The common
126+ // usage of `*` is in custom methods which don't use the URL at all for
127+ // transferring data.
128+ //
129+ // It is possible to define multiple HTTP methods for one RPC by using the
130+ // `additional_bindings` option. Example:
131+ //
132+ // service Messaging { rpc GetMessage(GetMessageRequest) returns (Message) {
133+ // option (google.api.http) = { get: "/v1/messages/{message_id}"
134+ // additional_bindings { get: "/v1/users/{user_id}/messages/{message_id}" } }; }
135+ // } message GetMessageRequest { string message_id = 1; string user_id = 2; }
136+ //
137+ // This enables the following two alternative HTTP JSON to RPC mappings:
138+ //
139+ // HTTP | gRPC -----|----- `GET /v1/messages/123456` | `GetMessage(message_id:
140+ // "123456")` `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me"
141+ // message_id: "123456")`
142+ //
143+ // ## Rules for HTTP mapping
144+ //
145+ // 1. Leaf request fields (recursive expansion nested messages in the request
146+ // message) are classified into three categories: - Fields referred by the path
147+ // template. They are passed via the URL path. - Fields referred by the
148+ // [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP
149+ // request body. - All other fields are passed via the URL query parameters, and
150+ // the parameter name is the field path in the request message. A repeated field
151+ // can be represented as multiple query parameters under the same name. 2. If
152+ // [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query
153+ // parameter, all fields are passed via URL path and HTTP request body. 3. If
154+ // [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP
155+ // request body, all fields are passed via URL path and URL query parameters.
156+ //
157+ // ### Path template syntax
158+ //
159+ // Template = "/" Segments [ Verb ] ; Segments = Segment { "/" Segment } ;
160+ // Segment = "*" | "**" | LITERAL | Variable ; Variable = "{" FieldPath [ "="
161+ // Segments ] "}" ; FieldPath = IDENT { "." IDENT } ; Verb = ":" LITERAL ;
162+ //
163+ // The syntax `*` matches a single URL path segment. The syntax `**` matches
164+ // zero or more URL path segments, which must be the last part of the URL path
165+ // except the `Verb`.
166+ //
167+ // The syntax `Variable` matches part of the URL path as specified by its
168+ // template. A variable template must not contain other variables. If a variable
169+ // matches a single path segment, its template may be omitted, e.g. `{var}` is
170+ // equivalent to `{var=*}`.
171+ //
172+ // The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL`
173+ // contains any reserved character, such characters should be percent-encoded
174+ // before the matching.
175+ //
176+ // If a variable contains exactly one path segment, such as `"{var}"` or
177+ // `"{var=*}"`, when such a variable is expanded into a URL path on the client
178+ // side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The server
179+ // side does the reverse decoding. Such variables show up in the [Discovery
180+ // Document] as `{var}`.
181+ //
182+ // If a variable contains multiple path segments, such as `"{var=foo/*}"` or
183+ // `"{var=**}"`, when such a variable is expanded into a URL path on the client
184+ // side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. The
185+ // server side does the reverse decoding, except "%2F" and "%2f" are left
186+ // unchanged. Such variables show up in the [Discovery Document] as `{+var}`.
187+ //
188+ // ## Using gRPC API Service Configuration
189+ //
190+ // gRPC API Service Configuration (service config) is a configuration language
191+ // for configuring a gRPC service to become a user-facing product. The service
192+ // config is simply the YAML representation of the `google.api.Service` proto
193+ // message.
194+ //
195+ // As an alternative to annotating your proto file, you can configure gRPC
196+ // transcoding in your service config YAML files. You do this by specifying a
197+ // `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same
198+ // effect as the proto annotation. This can be particularly useful if you have a
199+ // proto that is reused in multiple services. Note that any transcoding
200+ // specified in the service config will override any matching transcoding
201+ // configuration in the proto.
202+ //
203+ // Example:
204+ //
205+ // http: rules: # Selects a gRPC method and applies HttpRule to it. - selector:
206+ // example.v1.Messaging.GetMessage get: /v1/messages/{message_id}/{sub.subfield}
207+ //
208+ // ## Special notes
209+ //
210+ // When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the proto
211+ // to JSON conversion must follow the [proto3 specification].
212+ //
213+ // While the single segment variable follows the semantics of [RFC 6570] Section
214+ // 3.2.2 Simple String Expansion, the multi segment variable **does not** follow
215+ // RFC 6570 Section 3.2.3 Reserved Expansion. The reason is that the Reserved
216+ // Expansion does not expand special characters like `?` and `#`, which would
217+ // lead to invalid URLs. As the result, gRPC Transcoding uses a custom encoding
218+ // for multi segment variables.
219+ //
220+ // The path variables **must not** refer to any repeated or mapped field,
221+ // because client libraries are not capable of handling such variable expansion.
222+ //
223+ // The path variables **must not** capture the leading "/" character. The reason
224+ // is that the most common use case "{var}" does not capture the leading "/"
225+ // character. For consistency, all path variables must share the same behavior.
226+ //
227+ // Repeated message fields must not be mapped to URL query parameters, because
228+ // no client library can support such complicated mapping.
229+ //
230+ // If an API needs to use a JSON array for request or response body, it can map
231+ // the request or response body to a repeated field. However, some gRPC
232+ // Transcoding implementations may not support this feature.
233+ //
234+ // [Cloud Endpoints]: https://cloud.google.com/endpoints
235+ // [Discovery Document]: https://developers.google.com/discovery/v1/reference/apis
236+ // [Envoy]: https://github.com/envoyproxy/envoy
237+ // [Google
238+ APIs]: https://github.com/googleapis/googleapis
239+ // [RFC 6570]: https://tools.ietf.org/html/rfc6570
240+ // [gRPC
241+ Gateway]: https://github.com/grpc-ecosystem/grpc-gateway
242+ // [proto3
243+ specification]: https://developers.google.com/protocol-buffers/docs/proto3#json
54244type HttpRule struct {
55-
56245 Selector * string `json:"selector"`
57-
58246 Get * string `json:"get"`
59-
60247 Put * string `json:"put"`
61-
62248 Post * string `json:"post"`
63-
64249 Delete * string `json:"delete"`
65-
66250 Patch * string `json:"patch"`
67-
68251 Custom * CustomHttpPattern `json:"custom"`
69-
70252 Body * string `json:"body"`
71-
72253 ResponseBody * string `json:"responseBody"`
73-
74254 AdditionalBindings []HttpRule `json:"additionalBindings"`
75-
76255}
77-
78-
0 commit comments