1<div align="center">
2<h1>gRPC-Gateway</h1>
3<p>
4gRPC to JSON proxy generator following the gRPC HTTP spec
5</p>
6<a href="https://github.com/grpc-ecosystem/grpc-gateway/actions/workflows/main.yml"><img src="https://img.shields.io/github/workflow/status/grpc-ecosystem/grpc-gateway/main?color=379c9c&label=build&logo=github&logoColor=ffffff&style=flat-square"/></a>
7<a href="https://app.slack.com/client/T029RQSE6/CBATURP1D"><img src="https://img.shields.io/badge/slack-grpc--gateway-379c9c?logo=slack&logoColor=ffffff&style=flat-square"/></a>
8<a href="https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE"><img src="https://img.shields.io/github/license/grpc-ecosystem/grpc-gateway?color=379c9c&style=flat-square"/></a>
9<a href="https://github.com/grpc-ecosystem/grpc-gateway/releases"><img src="https://img.shields.io/github/v/release/grpc-ecosystem/grpc-gateway?color=379c9c&logoColor=ffffff&style=flat-square"/></a>
10<a href="https://github.com/grpc-ecosystem/grpc-gateway/stargazers"><img src="https://img.shields.io/github/stars/grpc-ecosystem/grpc-gateway?color=379c9c&style=flat-square"/></a>
11<a href="https://slsa.dev/images/gh-badge-level3.svg"><img src="https://slsa.dev/images/gh-badge-level3.svg"/></a>
12
13</div>
14
15## About
16
17The gRPC-Gateway is a plugin of the Google protocol buffers compiler
18[protoc](https://github.com/protocolbuffers/protobuf).
19It reads protobuf service definitions and generates a reverse-proxy server which
20translates a RESTful HTTP API into gRPC. This server is generated according to the
21[`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46)
22annotations in your service definitions.
23
24This helps you provide your APIs in both gRPC and RESTful style at the same time.
25
26<div align="center">
27<img src="docs/assets/images/architecture_introduction_diagram.svg" />
28</div>
29
30## Docs
31
32You can read our docs at:
33
34- https://grpc-ecosystem.github.io/grpc-gateway/
35
36## Testimonials
37
38> We use the gRPC-Gateway to serve millions of API requests per day,
39> and have been since 2018 and through all of that,
40> we have never had any issues with it.
41>
42> _- William Mill, [Ad Hoc](http://adhocteam.us/)_
43
44## Background
45
46gRPC is great -- it generates API clients and server stubs in many programming
47languages, it is fast, easy-to-use, bandwidth-efficient and its design is
48combat-proven by Google. However, you might still want to provide a traditional
49RESTful JSON API as well. Reasons can range from maintaining
50backward-compatibility, supporting languages or clients that are not well supported by
51gRPC, to simply maintaining the aesthetics and tooling involved with a RESTful
52JSON architecture.
53
54This project aims to provide that HTTP+JSON interface to your gRPC service.
55A small amount of configuration in your service to attach HTTP semantics is all
56that's needed to generate a reverse-proxy with this library.
57
58## Installation
59
60### Compile from source
61
62The following instructions assume you are using
63[Go Modules](https://github.com/golang/go/wiki/Modules) for dependency
64management. Use a
65[tool dependency](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
66to track the versions of the following executable packages:
67
68```go
69// +build tools
70
71package tools
72
73import (
74 _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
75 _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
76 _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
77 _ "google.golang.org/protobuf/cmd/protoc-gen-go"
78)
79```
80
81Run `go mod tidy` to resolve the versions. Install by running
82
83```sh
84$ go install \
85 github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
86 github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
87 google.golang.org/protobuf/cmd/protoc-gen-go \
88 google.golang.org/grpc/cmd/protoc-gen-go-grpc
89```
90
91This will place four binaries in your `$GOBIN`;
92
93- `protoc-gen-grpc-gateway`
94- `protoc-gen-openapiv2`
95- `protoc-gen-go`
96- `protoc-gen-go-grpc`
97
98Make sure that your `$GOBIN` is in your `$PATH`.
99
100### Download the binaries
101
102You may alternatively download the binaries from the [GitHub releases page](https://github.com/grpc-ecosystem/grpc-gateway/releases/latest).
103We generate [SLSA3 signatures](slsa.dev) using the OpenSSF's [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) during the release process. To verify a release binary:
104
1051. Install the verification tool from [slsa-framework/slsa-verifier#installation](https://github.com/slsa-framework/slsa-verifier#installation).
1062. Download the provenance file `attestation.intoto.jsonl` from the [GitHub releases page](https://github.com/grpc-ecosystem/grpc-gateway/releases/latest).
1073. Run the verifier:
108
109```shell
110slsa-verifier -artifact-path <the-binary> -provenance attestation.intoto.jsonl -source github.com/grpc-ecosystem/grpc-gateway -tag <the-tag>
111```
112
113Alternatively, see the section on remotely managed plugin versions below.
114
115## Usage
116
117### 1.Define your [gRPC](https://grpc.io/docs/) service using protocol buffers
118
119`your_service.proto`:
120
121```protobuf
122 syntax = "proto3";
123 package your.service.v1;
124 option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
125
126 message StringMessage {
127 string value = 1;
128 }
129
130 service YourService {
131 rpc Echo(StringMessage) returns (StringMessage) {}
132 }
133```
134
135### 2. Generate gRPC stubs
136
137This step generates the gRPC stubs that you can use to implement the service and consume from clients:
138
139Here's an example `buf.gen.yaml` you can use to generate the stubs with [buf](https://github.com/bufbuild/buf):
140
141```yaml
142version: v1
143plugins:
144 - plugin: go
145 out: gen/go
146 opt:
147 - paths=source_relative
148 - plugin: go-grpc
149 out: gen/go
150 opt:
151 - paths=source_relative
152```
153
154With this file in place, you can generate your files using `buf generate`.
155
156> For a complete example of using `buf generate` to generate protobuf stubs, see
157> [the boilerplate repo](https://github.com/johanbrandhorst/grpc-gateway-boilerplate).
158> For more information on generating the stubs with buf, see
159> [the official documentation](https://docs.buf.build/generate-usage).
160
161If you are using `protoc` to generate stubs, here's an example of what a command
162might look like:
163
164```sh
165protoc -I . \
166 --go_out ./gen/go/ --go_opt paths=source_relative \
167 --go-grpc_out ./gen/go/ --go-grpc_opt paths=source_relative \
168 your/service/v1/your_service.proto
169```
170
171### 3. Implement your service in gRPC as usual.
172
173### 4. Generate reverse-proxy using `protoc-gen-grpc-gateway`
174
175At this point, you have 3 options:
176
177- no further modifications, use the default mapping to HTTP semantics (method, path, etc.)
178 - this will work on any `.proto` file, but will not allow setting HTTP paths, request parameters or similar
179- additional `.proto` modifications to use a custom mapping
180 - relies on parameters in the `.proto` file to set custom HTTP mappings
181- no `.proto` modifications, but use an external configuration file
182 - relies on an external configuration file to set custom HTTP mappings
183 - mostly useful when the source proto file isn't under your control
184
185#### 1. Using the default mapping
186
187This requires no additional modification to the `.proto` file but does require enabling a specific option when executing the plugin.
188The `generate_unbound_methods` should be enabled.
189
190Here's what a `buf.gen.yaml` file might look like with this option enabled:
191
192```yaml
193version: v1
194plugins:
195 - plugin: go
196 out: gen/go
197 opt:
198 - paths=source_relative
199 - plugin: go-grpc
200 out: gen/go
201 opt:
202 - paths=source_relative
203 - plugin: grpc-gateway
204 out: gen/go
205 opt:
206 - paths=source_relative
207 - generate_unbound_methods=true
208```
209
210With `protoc` (just the grpc-gateway stubs):
211
212```sh
213protoc -I . --grpc-gateway_out ./gen/go \
214 --grpc-gateway_opt paths=source_relative \
215 --grpc-gateway_opt generate_unbound_methods=true \
216 your/service/v1/your_service.proto
217```
218
219#### 2. With custom annotations
220
221Add a [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46)
222annotation to your .proto file
223
224`your_service.proto`:
225
226```diff
227 syntax = "proto3";
228 package your.service.v1;
229 option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
230+
231+import "google/api/annotations.proto";
232+
233 message StringMessage {
234 string value = 1;
235 }
236
237 service YourService {
238- rpc Echo(StringMessage) returns (StringMessage) {}
239+ rpc Echo(StringMessage) returns (StringMessage) {
240+ option (google.api.http) = {
241+ post: "/v1/example/echo"
242+ body: "*"
243+ };
244+ }
245 }
246```
247
248> You will need to provide the required third party protobuf files to the protobuf compiler.
249> If you are using [buf](https://github.com/bufbuild/buf), this dependency can
250> be added to the `deps` array in your `buf.yaml` under the name
251> `buf.build/googleapis/googleapis`:
252>
253> ```yaml
254> version: v1
255> name: buf.build/yourorg/myprotos
256> deps:
257> - buf.build/googleapis/googleapis
258> ```
259>
260> Always run `buf mod update` after adding a dependency to your `buf.yaml`.
261
262See [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto)
263for examples of more annotations you can add to customize gateway behavior
264and generated OpenAPI output.
265
266Here's what a `buf.gen.yaml` file might look like:
267
268```yaml
269version: v1
270plugins:
271 - plugin: go
272 out: gen/go
273 opt:
274 - paths=source_relative
275 - plugin: go-grpc
276 out: gen/go
277 opt:
278 - paths=source_relative
279 - plugin: grpc-gateway
280 out: gen/go
281 opt:
282 - paths=source_relative
283```
284
285If you are using `protoc` to generate stubs, you need to ensure the required
286dependencies are available to the compiler at compile time. These can be found
287by manually cloning and copying the relevant files from the
288[googleapis repository](https://github.com/googleapis/googleapis), and providing
289them to `protoc` when running. The files you will need are:
290
291```
292google/api/annotations.proto
293google/api/field_behavior.proto
294google/api/http.proto
295google/api/httpbody.proto
296```
297
298Here's what a `protoc` execution might look like:
299
300```sh
301protoc -I . --grpc-gateway_out ./gen/go \
302 --grpc-gateway_opt paths=source_relative \
303 your/service/v1/your_service.proto
304```
305
306#### 3. External configuration
307
308If you do not want to (or cannot) modify the proto file for use with gRPC-Gateway you can
309alternatively use an external
310[gRPC Service Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) file.
311[Check our documentation](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/grpc_api_configuration/)
312for more information. This is best combined with the `standalone=true` option
313to generate a file that can live in its own package, separate from the files
314generated by the source protobuf file.
315
316Here's what a `buf.gen.yaml` file might look like with this option enabled:
317
318```yaml
319version: v1
320plugins:
321 - plugin: go
322 out: gen/go
323 opt:
324 - paths=source_relative
325 - plugin: go-grpc
326 out: gen/go
327 opt:
328 - paths=source_relative
329 - plugin: grpc-gateway
330 out: gen/go
331 opt:
332 - paths=source_relative
333 - grpc_api_configuration=path/to/config.yaml
334 - standalone=true
335```
336
337With `protoc` (just the grpc-gateway stubs):
338
339```sh
340protoc -I . --grpc-gateway_out ./gen/go \
341 --grpc-gateway_opt paths=source_relative \
342 --grpc-gateway_opt grpc_api_configuration=path/to/config.yaml \
343 --grpc-gateway_opt standalone=true \
344 your/service/v1/your_service.proto
345```
346
347### 5. Write an entrypoint for the HTTP reverse-proxy server
348
349```go
350package main
351
352import (
353 "context"
354 "flag"
355 "net/http"
356
357 "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
358 "google.golang.org/grpc"
359 "google.golang.org/grpc/credentials/insecure"
360 "google.golang.org/grpc/grpclog"
361
362 gw "github.com/yourorg/yourrepo/proto/gen/go/your/service/v1/your_service" // Update
363)
364
365var (
366 // command-line options:
367 // gRPC server endpoint
368 grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint")
369)
370
371func run() error {
372 ctx := context.Background()
373 ctx, cancel := context.WithCancel(ctx)
374 defer cancel()
375
376 // Register gRPC server endpoint
377 // Note: Make sure the gRPC server is running properly and accessible
378 mux := runtime.NewServeMux()
379 opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
380 err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
381 if err != nil {
382 return err
383 }
384
385 // Start HTTP server (and proxy calls to gRPC server endpoint)
386 return http.ListenAndServe(":8081", mux)
387}
388
389func main() {
390 flag.Parse()
391
392 if err := run(); err != nil {
393 grpclog.Fatal(err)
394 }
395}
396```
397
398### 6. (Optional) Generate OpenAPI definitions using `protoc-gen-openapiv2`
399
400Here's what a `buf.gen.yaml` file might look like:
401
402```yaml
403version: v1
404plugins:
405 - plugin: go
406 out: gen/go
407 opt:
408 - paths=source_relative
409 - plugin: go-grpc
410 out: gen/go
411 opt:
412 - paths=source_relative
413 - plugin: grpc-gateway
414 out: gen/go
415 opt:
416 - paths=source_relative
417 - plugin: openapiv2
418 out: gen/openapiv2
419```
420
421To use the custom protobuf annotations supported by `protoc-gen-openapiv2`, we need
422another dependency added to our protobuf generation step. If you are using
423`buf`, you can add the `buf.build/grpc-ecosystem/grpc-gateway` dependency
424to your `deps` array:
425
426```yaml
427version: v1
428name: buf.build/yourorg/myprotos
429deps:
430 - buf.build/googleapis/googleapis
431 - buf.build/grpc-ecosystem/grpc-gateway
432```
433
434With `protoc` (just the swagger file):
435
436```sh
437protoc -I . --openapiv2_out ./gen/openapiv2 \
438 your/service/v1/your_service.proto
439```
440
441If you are using `protoc` to generate stubs, you will need to copy the protobuf
442files from the `protoc-gen-openapiv2/options` directory of this repository,
443and providing them to `protoc` when running.
444
445Note that this plugin also supports generating OpenAPI definitions for unannotated methods;
446use the `generate_unbound_methods` option to enable this.
447
448It is possible with the HTTP mapping for a gRPC service method to create duplicate mappings
449with the only difference being constraints on the path parameter.
450
451`/v1/{name=projects/*}` and `/v1/{name=organizations/*}` both become `/v1/{name}`. When
452this occurs the plugin will rename the path parameter with a "\_1" (or "\_2" etc) suffix
453to differentiate the different operations. So in the above example, the 2nd path would become
454`/v1/{name_1=organizations/*}`. This can also cause OpenAPI clients to URL encode the "/" that is
455part of the path parameter as that is what OpenAPI defines in the specification. To allow gRPC gateway to
456accept the URL encoded slash and still route the request, use the UnescapingModeAllCharacters or
457UnescapingModeLegacy (which is the default currently though may change in future versions). See
458[Customizing Your Gateway](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_your_gateway/)
459for more information.
460
461## Usage with remote plugins
462
463As an alternative to all of the above, you can use `buf` with
464[remote plugins](https://docs.buf.build/configuration/v1/buf-gen-yaml#name-or-remote)
465to manage plugin versions and generation. An example `buf.gen.yaml` using remote
466plugin generation looks like this:
467
468```yaml
469version: v1
470plugins:
471 - plugin: buf.build/protocolbuffers/go:v1.31.0
472 out: gen/go
473 opt:
474 - paths=source_relative
475 - plugin: buf.build/grpc/go:v1.3.0
476 out: gen/go
477 opt:
478 - paths=source_relative
479 - plugin: buf.build/grpc-ecosystem/gateway:v2.16.2
480 out: gen/go
481 opt:
482 - paths=source_relative
483 - plugin: buf.build/grpc-ecosystem/openapiv2:v2.16.2
484 out: gen/openapiv2
485```
486
487This requires no local installation of any plugins. Be careful to use the same
488version of the generator as the runtime library, i.e. if using `v2.16.2`, run
489
490```shell
491$ go get github.com/grpc-ecosystem/grpc-gateway/v2@v2.16.2
492```
493
494To get the same version of the runtime in your `go.mod`.
495
496Note that usage of remote plugins is incompatible with usage of external configuration files like [grpc_api_configuration](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/grpc_api_configuration/#using-an-external-configuration-file).
497
498## Video intro
499
500This GopherCon UK 2019 presentation from our maintainer [@JohanBrandhorst](https://github.com/johanbrandhorst) provides a good intro to using the gRPC-Gateway. It uses the following boilerplate repo as a base: https://github.com/johanbrandhorst/grpc-gateway-boilerplate.
501
502<div align="center">
503<a href="https://www.youtube.com/watch?v=Pq1paKC-fXk">
504<img src="https://img.youtube.com/vi/Pq1paKC-fXk/0.jpg" />
505</a>
506</div>
507
508## Parameters and flags
509
510When using `buf` to generate stubs, flags and parameters are passed through
511the `opt` field in your `buf.gen.yaml` file, for example:
512
513```yaml
514version: v1
515plugins:
516 - plugin: grpc-gateway
517 out: gen/go
518 opt:
519 - paths=source_relative
520 - grpc_api_configuration=path/to/config.yaml
521 - standalone=true
522```
523
524During code generation with `protoc`, flags to gRPC-Gateway tools must be passed
525through `protoc` using one of 2 patterns:
526
527- as part of the `--<tool_suffix>_out` `protoc` parameter: `--<tool_suffix>_out=<flags>:<path>`
528
529```sh
530--grpc-gateway_out=repeated_path_param_separator=ssv:.
531--openapiv2_out=repeated_path_param_separator=ssv:.
532```
533
534- using additional `--<tool_suffix>_opt` parameters: `--<tool_suffix>_opt=<flag>[,<flag>]*`
535
536```sh
537--grpc-gateway_opt repeated_path_param_separator=ssv
538--openapiv2_opt repeated_path_param_separator=ssv
539```
540
541## More examples
542
543More examples are available under the `examples` directory.
544
545- `proto/examplepb/echo_service.proto`, `proto/examplepb/a_bit_of_everything.proto`, `proto/examplepb/unannotated_echo_service.proto`: service definition
546 - `proto/examplepb/echo_service.pb.go`, `proto/examplepb/a_bit_of_everything.pb.go`, `proto/examplepb/unannotated_echo_service.pb.go`: [generated] stub of the service
547 - `proto/examplepb/echo_service.pb.gw.go`, `proto/examplepb/a_bit_of_everything.pb.gw.go`, `proto/examplepb/uannotated_echo_service.pb.gw.go`: [generated] reverse proxy for the service
548 - `proto/examplepb/unannotated_echo_service.yaml`: gRPC API Configuration for `unannotated_echo_service.proto`
549- `server/main.go`: service implementation
550- `main.go`: entrypoint of the generated reverse proxy
551
552To use the same port for custom HTTP handlers (e.g. serving `swagger.json`),
553gRPC-Gateway, and a gRPC server, see
554[this example by CoreOS](https://github.com/philips/grpc-gateway-example/blob/master/cmd/serve.go)
555(and its accompanying [blog post](https://web.archive.org/web/20201112010739/https://coreos.com/blog/grpc-protobufs-swagger.html)).
556
557[This example by neiro.ai](https://github.com/mynalabsai/grpc_gateway_media_example) (and its accompanying [blog post](https://medium.com/neiro-ai/grpc-gateway-for-media-api-by-neiro-9033caab12c8)) shows how mediafiles using `multipart/form-data` can be integrated into rpc messages using a middleware.
558
559## Features
560
561### Supported
562
563- Generating JSON API handlers.
564- Method parameters in the request body.
565- Method parameters in the request path.
566- Method parameters in the query string.
567- Enum fields in the path parameter (including repeated enum fields).
568- Mapping streaming APIs to newline-delimited JSON streams.
569- Mapping HTTP headers with `Grpc-Metadata-` prefix to gRPC metadata (prefixed with `grpcgateway-`)
570- Optionally emitting API definitions for
571 [OpenAPI (Swagger) v2](https://swagger.io/docs/specification/2-0/basic-structure/).
572- Setting [gRPC timeouts](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests)
573 through inbound HTTP `Grpc-Timeout` header.
574- Partial support for [gRPC API Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config)
575 files as an alternative to annotation.
576- Automatically translating PATCH requests into Field Mask gRPC requests. See
577 [the docs](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/patch_feature/)
578 for more information.
579
580### No plan to support
581
582But patches are welcome.
583
584- Method parameters in HTTP headers.
585- Handling trailer metadata.
586- Encoding request/response body in XML.
587- True bi-directional streaming.
588
589## Mapping gRPC to HTTP
590
591- [How gRPC error codes map to HTTP status codes in the response](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go#L15).
592- HTTP request source IP is added as `X-Forwarded-For` gRPC request header.
593- HTTP request host is added as `X-Forwarded-Host` gRPC request header.
594- HTTP `Authorization` header is added as `authorization` gRPC request header.
595- Remaining Permanent HTTP header keys (as specified by the IANA
596 [here](http://www.iana.org/assignments/message-headers/message-headers.xhtml))
597 are prefixed with `grpcgateway-` and added with their values to gRPC request
598 header.
599- HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata
600 (prefixed with `grpcgateway-`).
601- While configurable, the default {un,}marshaling uses
602 [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson).
603- The path template used to map gRPC service methods to HTTP endpoints supports the [google.api.http](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto)
604 path template syntax. For example, `/api/v1/{name=projects/*/topics/*}` or `/prefix/{path=organizations/**}`.
605
606## Contribution
607
608See [CONTRIBUTING.md](http://github.com/grpc-ecosystem/grpc-gateway/blob/main/CONTRIBUTING.md).
609
610## License
611
612gRPC-Gateway is licensed under the BSD 3-Clause License.
613See [LICENSE](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE) for more details.
View as plain text