-grpc-gateway is a plugin of [protoc](http://github.com/google/protobuf).
-It reads [gRPC](http://github.com/grpc/grpc-common) service definition,
-and generates a reverse-proxy server which translates a RESTful JSON API into gRPC.
-This server is generated according to [custom options](https://cloud.google.com/service-management/reference/rpc/google.api#http) in your gRPC definition.
+## About
-It helps you to provide your APIs in both gRPC and RESTful style at the same time.
+The gRPC-Gateway is a plugin of the Google protocol buffers compiler
+[protoc](https://github.com/protocolbuffers/protobuf).
+It reads protobuf service definitions and generates a reverse-proxy server which
+translates a RESTful HTTP API into gRPC. This server is generated according to the
+[`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46)
+annotations in your service definitions.
-
+This helps you provide your APIs in both gRPC and RESTful style at the same time.
-## Check out our [documentation](https://grpc-ecosystem.github.io/grpc-gateway/)!
+
+
+
+
+## Docs
+
+You can read our docs at:
+
+- https://grpc-ecosystem.github.io/grpc-gateway/
+
+## Testimonials
+
+> We use the gRPC-Gateway to serve millions of API requests per day,
+> and have been since 2018 and through all of that,
+> we have never had any issues with it.
+>
+> _- William Mill, [Ad Hoc](http://adhocteam.us/)_
## Background
-gRPC is great -- it generates API clients and server stubs in many programming languages, it is fast, easy-to-use, bandwidth-efficient and its design is combat-proven by Google.
-However, you might still want to provide a traditional RESTful API as well. Reasons can range from maintaining backwards-compatibility, supporting languages or clients not well supported by gRPC to simply maintaining the aesthetics and tooling involved with a RESTful architecture.
-This project aims to provide that HTTP+JSON interface to your gRPC service. A small amount of configuration in your service to attach HTTP semantics is all that's needed to generate a reverse-proxy with this library.
+gRPC is great -- it generates API clients and server stubs in many programming
+languages, it is fast, easy-to-use, bandwidth-efficient and its design is
+combat-proven by Google. However, you might still want to provide a traditional
+RESTful JSON API as well. Reasons can range from maintaining
+backward-compatibility, supporting languages or clients that are not well supported by
+gRPC, to simply maintaining the aesthetics and tooling involved with a RESTful
+JSON architecture.
+
+This project aims to provide that HTTP+JSON interface to your gRPC service.
+A small amount of configuration in your service to attach HTTP semantics is all
+that's needed to generate a reverse-proxy with this library.
## Installation
-First you need to install ProtocolBuffers 3.0.0-beta-3 or later.
-```sh
-mkdir tmp
-cd tmp
-git clone https://github.com/google/protobuf
-cd protobuf
-./autogen.sh
-./configure
-make
-make check
-sudo make install
+### Compile from source
+The following instructions assume you are using
+[Go Modules](https://github.com/golang/go/wiki/Modules) for dependency
+management. Use a
+[tool dependency](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
+to track the versions of the following executable packages:
+
+```go
+// +build tools
+
+package tools
+
+import (
+ _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
+ _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
+ _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
+ _ "google.golang.org/protobuf/cmd/protoc-gen-go"
+)
```
-Then, `go get -u` as usual the following packages:
+Run `go mod tidy` to resolve the versions. Install by running
```sh
-go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
-go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
-go get -u github.com/golang/protobuf/protoc-gen-go
+$ go install \
+ github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
+ github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
+ google.golang.org/protobuf/cmd/protoc-gen-go \
+ google.golang.org/grpc/cmd/protoc-gen-go-grpc
```
-
+
+This will place four binaries in your `$GOBIN`;
+
+- `protoc-gen-grpc-gateway`
+- `protoc-gen-openapiv2`
+- `protoc-gen-go`
+- `protoc-gen-go-grpc`
+
+Make sure that your `$GOBIN` is in your `$PATH`.
+
+### Download the binaries
+
+You may alternatively download the binaries from the [GitHub releases page](https://github.com/grpc-ecosystem/grpc-gateway/releases/latest).
+We 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:
+1. Install the verification tool from [slsa-framework/slsa-verifier#installation](https://github.com/slsa-framework/slsa-verifier#installation).
+2. Download the provenance file `attestation.intoto.jsonl` from the [GitHub releases page](https://github.com/grpc-ecosystem/grpc-gateway/releases/latest).
+3. Run the verifier:
+```shell
+slsa-verifier -artifact-path -provenance attestation.intoto.jsonl -source github.com/grpc-ecosystem/grpc-gateway -tag
+```
+
+Alternatively, see the section on remotely managed plugin versions below.
+
## Usage
-Make sure that your `$GOPATH/bin` is in your `$PATH`.
-1. Define your service in gRPC
-
- your_service.proto:
+1. Define your [gRPC](https://grpc.io/docs/) service using protocol buffers
+
+ `your_service.proto`:
+
```protobuf
- syntax = "proto3";
- package example;
- message StringMessage {
- string value = 1;
- }
-
- service YourService {
- rpc Echo(StringMessage) returns (StringMessage) {}
- }
+ syntax = "proto3";
+ package your.service.v1;
+ option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
+
+ message StringMessage {
+ string value = 1;
+ }
+
+ service YourService {
+ rpc Echo(StringMessage) returns (StringMessage) {}
+ }
```
-2. Add a [custom option](https://cloud.google.com/service-management/reference/rpc/google.api#http) to the .proto file
-
- your_service.proto:
+
+2. Generate gRPC stubs
+
+ This step generates the gRPC stubs that you can use to implement the service and consume from clients:
+
+ Here's an example `buf.gen.yaml` you can use to generate the stubs with [buf](https://github.com/bufbuild/buf):
+
+ ```yaml
+ version: v1
+ plugins:
+ - name: go
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: go-grpc
+ out: gen/go
+ opt:
+ - paths=source_relative
+ ```
+
+ With this file in place, you can generate your files using `buf generate`.
+
+ > For a complete example of using `buf generate` to generate protobuf stubs, see
+ > [the boilerplate repo](https://github.com/johanbrandhorst/grpc-gateway-boilerplate).
+ > For more information on generating the stubs with buf, see
+ > [the official documentation](https://docs.buf.build/generate-usage).
+
+ If you are using `protoc` to generate stubs, here's an example of what a command
+ might look like:
+
+ ```sh
+ protoc -I . \
+ --go_out ./gen/go/ --go_opt paths=source_relative \
+ --go-grpc_out ./gen/go/ --go-grpc_opt paths=source_relative \
+ your/service/v1/your_service.proto
+ ```
+
+3. Implement your service in gRPC as usual.
+
+4. Generate reverse-proxy using `protoc-gen-grpc-gateway`
+
+ At this point, you have 3 options:
+
+ - no further modifications, use the default mapping to HTTP semantics (method, path, etc.)
+ - this will work on any `.proto` file, but will not allow setting HTTP paths, request parameters or similar
+ - additional `.proto` modifications to use a custom mapping
+ - relies on parameters in the `.proto` file to set custom HTTP mappings
+ - no `.proto` modifications, but use an external configuration file
+ - relies on an external configuration file to set custom HTTP mappings
+ - mostly useful when the source proto file isn't under your control
+
+ 1. Using the default mapping
+
+ This requires no additional modification to the `.proto` file but does require enabling a specific option when executing the plugin.
+ The `generate_unbound_methods` should be enabled.
+
+ Here's what a `buf.gen.yaml` file might look like with this option enabled:
+
+ ```yaml
+ version: v1
+ plugins:
+ - name: go
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: go-grpc
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: grpc-gateway
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - generate_unbound_methods=true
+ ```
+
+ With `protoc` (just the grpc-gateway stubs):
+
+ ```sh
+ protoc -I . --grpc-gateway_out ./gen/go \
+ --grpc-gateway_opt logtostderr=true \
+ --grpc-gateway_opt paths=source_relative \
+ --grpc-gateway_opt generate_unbound_methods=true \
+ your/service/v1/your_service.proto
+ ```
+
+ 2. With custom annotations
+
+ Add a [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46)
+ annotation to your .proto file
+
+ `your_service.proto`:
+
```diff
syntax = "proto3";
- package example;
+ package your.service.v1;
+ option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
+
+import "google/api/annotations.proto";
+
message StringMessage {
string value = 1;
}
-
+
service YourService {
- rpc Echo(StringMessage) returns (StringMessage) {}
+ rpc Echo(StringMessage) returns (StringMessage) {
@@ -83,170 +243,369 @@ Make sure that your `$GOPATH/bin` is in your `$PATH`.
}
```
- If you do not want to modify the proto file for use with grpc-gateway you can alternatively use an external [gRPC API Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) file. [Check our documentation](https://grpc-ecosystem.github.io/grpc-gateway/docs/grpcapiconfiguration.html) for more information.
+ > You will need to provide the required third party protobuf files to the protobuf compiler.
+ > If you are using [buf](https://github.com/bufbuild/buf), this dependency can
+ > be added to the `deps` array in your `buf.yaml` under the name
+ > `buf.build/googleapis/googleapis`:
+ > ```yaml
+ > version: v1
+ > name: buf.build/yourorg/myprotos
+ > deps:
+ > - buf.build/googleapis/googleapis
+ > ```
+ > Always run `buf mod update` after adding a dependency to your `buf.yaml`.
+
+ See [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto)
+ for examples of more annotations you can add to customize gateway behavior
+ and generated OpenAPI output.
+
+ Here's what a `buf.gen.yaml` file might look like:
+
+ ```yaml
+ version: v1
+ plugins:
+ - name: go
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: go-grpc
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: grpc-gateway
+ out: gen/go
+ opt:
+ - paths=source_relative
+ ```
+
+ If you are using `protoc` to generate stubs, you need to ensure the required
+ dependencies are available to the compiler at compile time. These can be found
+ by manually cloning and copying the relevant files from the
+ [googleapis repository](https://github.com/googleapis/googleapis), and providing
+ them to `protoc` when running. The files you will need are:
+
+ ```
+ google/api/annotations.proto
+ google/api/field_behavior.proto
+ google/api/http.proto
+ google/api/httpbody.proto
+ ```
+
+ Here's what a `protoc` execution might look like:
-3. Generate gRPC stub
-
```sh
- protoc -I/usr/local/include -I. \
- -I$GOPATH/src \
- -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
- --go_out=plugins=grpc:. \
- path/to/your_service.proto
- ```
-
- It will generate a stub file `path/to/your_service.pb.go`.
-4. Implement your service in gRPC as usual
- 1. (Optional) Generate gRPC stub in the language you want.
-
- e.g.
- ```sh
- protoc -I/usr/local/include -I. \
- -I$GOPATH/src \
- -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
- --ruby_out=. \
- path/to/your/service_proto
-
- protoc -I/usr/local/include -I. \
- -I$GOPATH/src \
- -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
- --plugin=protoc-gen-grpc=grpc_ruby_plugin \
- --grpc-ruby_out=. \
- path/to/your/service.proto
- ```
- 2. Add the googleapis-common-protos gem (or your language equivalent) as a dependency to your project.
- 3. Implement your service
-
-5. Generate reverse-proxy
-
+ protoc -I . --grpc-gateway_out ./gen/go \
+ --grpc-gateway_opt logtostderr=true \
+ --grpc-gateway_opt paths=source_relative \
+ your/service/v1/your_service.proto
+ ```
+
+ 3. External configuration
+ If you do not want to (or cannot) modify the proto file for use with gRPC-Gateway you can
+ alternatively use an external
+ [gRPC Service Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) file.
+ [Check our documentation](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/grpc_api_configuration/)
+ for more information. This is best combined with the `standalone=true` option
+ to generate a file that can live in its own package, separate from the files
+ generated by the source protobuf file.
+
+ Here's what a `buf.gen.yaml` file might look like with this option enabled:
+
+ ```yaml
+ version: v1
+ plugins:
+ - name: go
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: go-grpc
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: grpc-gateway
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - grpc_api_configuration=path/to/config.yaml
+ - standalone=true
+ ```
+
+ With `protoc` (just the grpc-gateway stubs):
+
```sh
- protoc -I/usr/local/include -I. \
- -I$GOPATH/src \
- -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
- --grpc-gateway_out=logtostderr=true:. \
- path/to/your_service.proto
+ protoc -I . --grpc-gateway_out ./gen/go \
+ --grpc-gateway_opt logtostderr=true \
+ --grpc-gateway_opt paths=source_relative \
+ --grpc-gateway_opt grpc_api_configuration=path/to/config.yaml \
+ --grpc-gateway_opt standalone=true \
+ your/service/v1/your_service.proto
```
-
- It will generate a reverse proxy `path/to/your_service.pb.gw.go`.
- Note: After generating the code for each of the stubs, in order to build the code, you will want to run ```go get .``` from the directory containing the stubs.
+5. Write an entrypoint for the HTTP reverse-proxy server
-6. Write an entrypoint
-
- Now you need to write an entrypoint of the proxy server.
```go
package main
import (
+ "context"
"flag"
"net/http"
-
+
"github.com/golang/glog"
- "golang.org/x/net/context"
- "github.com/grpc-ecosystem/grpc-gateway/runtime"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
-
- gw "path/to/your_service_package"
+ "google.golang.org/grpc/credentials/insecure"
+
+ gw "github.com/yourorg/yourrepo/proto/gen/go/your/service/v1/your_service" // Update
)
-
+
var (
- echoEndpoint = flag.String("echo_endpoint", "localhost:9090", "endpoint of YourService")
+ // command-line options:
+ // gRPC server endpoint
+ grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint")
)
-
+
func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
-
+
+ // Register gRPC server endpoint
+ // Note: Make sure the gRPC server is running properly and accessible
mux := runtime.NewServeMux()
- opts := []grpc.DialOption{grpc.WithInsecure()}
- err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)
+ opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
+ err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
if err != nil {
return err
}
-
- return http.ListenAndServe(":8080", mux)
+
+ // Start HTTP server (and proxy calls to gRPC server endpoint)
+ return http.ListenAndServe(":8081", mux)
}
-
+
func main() {
flag.Parse()
defer glog.Flush()
-
+
if err := run(); err != nil {
glog.Fatal(err)
}
}
```
-7. (Optional) Generate swagger definitions
+6. (Optional) Generate OpenAPI definitions using `protoc-gen-openapiv2`
+
+ Here's what a `buf.gen.yaml` file might look like:
+
+ ```yaml
+ version: v1
+ plugins:
+ - name: go
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: go-grpc
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: grpc-gateway
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - name: openapiv2
+ out: gen/openapiv2
+ ```
+
+ To use the custom protobuf annotations supported by `protoc-gen-openapiv2`, we need
+ another dependency added to our protobuf generation step. If you are using
+ `buf`, you can add the `buf.build/grpc-ecosystem/grpc-gateway` dependency
+ to your `deps` array:
+ ```yaml
+ version: v1
+ name: buf.build/yourorg/myprotos
+ deps:
+ - buf.build/googleapis/googleapis
+ - buf.build/grpc-ecosystem/grpc-gateway
+ ```
+
+ With `protoc` (just the swagger file):
```sh
- protoc -I/usr/local/include -I. \
- -I$GOPATH/src \
- -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
- --swagger_out=logtostderr=true:. \
- path/to/your_service.proto
+ protoc -I . --openapiv2_out ./gen/openapiv2 \
+ --openapiv2_opt logtostderr=true \
+ your/service/v1/your_service.proto
```
+ If you are using `protoc` to generate stubs, you will need to copy the protobuf
+ files from the `protoc-gen-openapiv2/options` directory of this repository,
+ and providing them to `protoc` when running.
+
+ Note that this plugin also supports generating OpenAPI definitions for unannotated methods;
+ use the `generate_unbound_methods` option to enable this.
+
+ It is possible with the HTTP mapping for a gRPC service method to create duplicate mappings
+ with the only difference being constraints on the path parameter.
+
+ `/v1/{name=projects/*}` and `/v1/{name=organizations/*}` both become `/v1/{name}`. When
+ this occurs the plugin will rename the path parameter with a "_1" (or "_2" etc) suffix
+ to differentiate the different operations. So in the above example, the 2nd path would become
+ `/v1/{name_1=organizations/*}`. This can also cause OpenAPI clients to URL encode the "/" that is
+ part of the path parameter as that is what OpenAPI defines in the specification. To allow gRPC gateway to
+ accept the URL encoded slash and still route the request, use the UnescapingModeAllCharacters or
+ UnescapingModeLegacy (which is the default currently though may change in future versions). See
+ [Customizing Your Gateway](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_your_gateway/)
+ for more information.
+
+## Usage with remote plugins
+
+As an alternative to all of the above, you can use `buf` with
+[remote plugins](https://docs.buf.build/configuration/v1/buf-gen-yaml#name-or-remote)
+to manage plugin versions and generation. An example `buf.gen.yaml` using remote
+plugin generation looks like this:
+
+```yaml
+version: v1
+plugins:
+ - remote: buf.build/library/plugins/go:v1.27.1-1
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - remote: buf.build/library/plugins/go-grpc:v1.1.0-2
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - remote: buf.build/grpc-ecosystem/plugins/grpc-gateway:v2.6.0-1
+ out: gen/go
+ opt:
+ - paths=source_relative
+ - remote: buf.build/grpc-ecosystem/plugins/openapiv2:v2.6.0-1
+ out: gen/openapiv2
+```
+
+This requires no local installation of any plugins. Be careful to use the same
+version of the generator as the runtime library, i.e. if using `v2.6.0-1`, run
+
+```shell
+$ go get github.com/grpc-ecosystem/grpc-gateway/v2@v2.6.0
+```
+
+To get the same version of the runtime in your `go.mod`.
+
+## Video intro
+
+This 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.
+
+
+
diff --git a/docs/assets/images/architecture_introduction_diagram.svg b/docs/assets/images/architecture_introduction_diagram.svg
new file mode 100644
index 00000000000..3c9347e31a2
--- /dev/null
+++ b/docs/assets/images/architecture_introduction_diagram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/images/gotemplates/postman.png b/docs/assets/images/gotemplates/postman.png
new file mode 100644
index 00000000000..4f6fb7fb9c6
Binary files /dev/null and b/docs/assets/images/gotemplates/postman.png differ
diff --git a/docs/assets/images/gotemplates/swaggerui.png b/docs/assets/images/gotemplates/swaggerui.png
new file mode 100644
index 00000000000..02bf9ce1cb7
Binary files /dev/null and b/docs/assets/images/gotemplates/swaggerui.png differ
diff --git a/docs/docs/contributing/2020_season_of_docs.md b/docs/docs/contributing/2020_season_of_docs.md
new file mode 100644
index 00000000000..649dcb427bb
--- /dev/null
+++ b/docs/docs/contributing/2020_season_of_docs.md
@@ -0,0 +1,17 @@
+---
+layout: default
+title: Google Season of Docs
+nav_order: 1
+parent: Contributing
+---
+
+# 2020 Season of Docs
+
+
+
+
+
+The gRPC-Gateway participated in the 2020 [Google Season of Docs](https://g.co/seasonofdocs).
+The project was completed by [@iamrajiv](https://github.com/iamrajiv). A summary of the project
+work can be found in the
+[project report](https://github.com/iamrajiv/GSoD-2020/blob/master/GSoD_2020_Project_Report.md).
diff --git a/docs/docs/contributing/getting_started.md b/docs/docs/contributing/getting_started.md
new file mode 100644
index 00000000000..f2b52520136
--- /dev/null
+++ b/docs/docs/contributing/getting_started.md
@@ -0,0 +1,10 @@
+---
+layout: default
+title: Getting started
+nav_order: 0
+parent: Contributing
+---
+
+# How to contribute
+
+See [CONTRIBUTING.md](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/CONTRIBUTING.md).
diff --git a/docs/docs/contributing/index.md b/docs/docs/contributing/index.md
new file mode 100644
index 00000000000..4241bd25bc4
--- /dev/null
+++ b/docs/docs/contributing/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Contributing
+nav_order: 5
+has_children: true
+---
diff --git a/docs/docs/development/grpc-gateway_v2_migration_guide.md b/docs/docs/development/grpc-gateway_v2_migration_guide.md
new file mode 100644
index 00000000000..fe3b131e983
--- /dev/null
+++ b/docs/docs/development/grpc-gateway_v2_migration_guide.md
@@ -0,0 +1,168 @@
+---
+layout: default
+title: gRPC-Gateway v2 migration guide
+nav_order: 0
+parent: Development
+---
+
+# gRPC-Gateway v2 migration guide
+
+This guide is supposed to help users of the gateway migrate from v1 to v2. See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/1223) for detailed information on all changes that were made specifically to v2.
+
+The following behavioural defaults have been changed:
+
+## protoc-gen-swagger has been renamed protoc-gen-openapiv2
+
+See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/675)
+for more information. Apart from the new name, the only real difference to users will be a slightly different proto annotation:
+
+```protobuf
+import "protoc-gen-openapiv2/options/annotations.proto";
+```
+
+instead of
+
+```protobuf
+import "protoc-gen-swagger/options/annotations.proto";
+```
+
+and
+
+```protobuf
+option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+```
+
+instead of
+
+```protobuf
+option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
+```
+
+The Bazel rule has been renamed `protoc_gen_openapiv2`.
+
+## The example field in the OpenAPI annotations is now a string
+
+This was a `google.protobuf.Any` type, but it was only used for the JSON representation, and it was breaking some tools and it was generally unclear to the user how it works. It is now a string instead. The value is copied verbatim to the output OpenAPI file. Remember to escape any quotes in the strings.
+
+For example, if you had an example that looked like this:
+
+```protobuf
+example: { value: '{ "uuid": "0cf361e1-4b44-483d-a159-54dabdf7e814" }' }
+```
+
+It would now look like this:
+
+```protobuf
+example: "{\"uuid\": \"0cf361e1-4b44-483d-a159-54dabdf7e814\"}"
+```
+
+See [a_bit_of_everything.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto) in the example protos for more examples.
+
+## We now use the camelCase JSON names by default
+
+See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/375) and
+[original pull request](https://github.com/grpc-ecosystem/grpc-gateway/pull/540) for more information.
+
+If you want to revert to the old behaviour, configure a custom marshaler with `UseProtoNames: true`:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{
+ Marshaler: &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ UseProtoNames: true,
+ EmitUnpopulated: true,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ },
+ }),
+)
+```
+
+To change the OpenAPI generator behaviour to match, set `json_names_for_fields=false` when generating:
+
+```sh
+--openapiv2_out=json_names_for_fields=false:./gen/openapiv2 path/to/my/proto/v1/myproto.proto
+```
+
+If using the Bazel rule, set `json_names_for_fields=False`.
+
+## We now emit default values for all fields
+
+See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/233)
+for more information.
+
+If you want to revert to the old behaviour, configure a custom marshaler with
+`EmitUnpopulated: false`:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{
+ Marshaler: &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ EmitUnpopulated: false,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ },
+ }),
+)
+```
+
+## We now support google.api.HttpBody message types by default
+
+The `runtime.SetHTTPBodyMarshaler` function has disappeared, and is now
+enabled by default. If you for some reason don't want `HttpBody` messages to be
+respected, you can disable it by overwriting the default marshaler with one which
+does not wrap `runtime.JSONPb` in `runtime.HTTPBodyMarshaler`:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ EmitUnpopulated: true,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ }),
+)
+```
+
+## runtime.DisallowUnknownFields has been removed
+
+All marshalling settings are now inherited from the configured marshaler. If you wish
+to disallow unknown fields, configure a custom marshaler:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{
+ Marshaler: &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ EmitUnpopulated: true,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: false,
+ },
+ },
+ }),
+)
+```
+
+## WithLastMatchWins and allow_colon_final_segments=true is now default behaviour
+
+If you were previously specifying these, please remove them, as this is now
+the default behaviour. See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/224) for more information.
+
+There is no workaround for this, as we considered it a correct interpretation of the spec. If this breaks your application, carefully consider the order in which you define your services.
+
+## Error handling configuration has been overhauled
+
+`runtime.HTTPError`, `runtime.OtherErrorHandler`, `runtime.GlobalHTTPErrorHandler`, `runtime.WithProtoErrorHandler` are all gone. Error handling is rewritten around the use of gRPCs Status types. If you wish to configure how the gateway handles errors, please use `runtime.WithErrorHandler` and `runtime.WithStreamErrorHandler`. To handle routing errors (similar to the removed `runtime.OtherErrorHandler`) please use `runtime.WithRoutingErrorHandler`.
+
+## Default query parameter parsing behaviour change
+
+The default behaviour for query parameter parsing has changed to return an `InvalidArgument` (`400 Bad Request`) error when more than one of the same matching query parameters is parsed. Previously, it would log but not return an error, using the first query parameter that matched and ignoring any others. See [the original issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/2632) for more information.
\ No newline at end of file
diff --git a/docs/docs/development/index.md b/docs/docs/development/index.md
new file mode 100644
index 00000000000..f953f4bafc2
--- /dev/null
+++ b/docs/docs/development/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Development
+nav_order: 4
+has_children: true
+---
diff --git a/docs/_docs/cygwin.md b/docs/docs/development/installation_for_cygwin.md
similarity index 55%
rename from docs/_docs/cygwin.md
rename to docs/docs/development/installation_for_cygwin.md
index 5e0a37fafa6..2ed9ed8aefa 100644
--- a/docs/_docs/cygwin.md
+++ b/docs/docs/development/installation_for_cygwin.md
@@ -1,31 +1,36 @@
---
-category: documentation
+layout: default
title: Installation for Cygwin
-order: 1000
+nav_order: 1
+parent: Development
---
-#Installation for Cygwin
+# Installation for Cygwin
+
+
+
+
-
## Installation
-First you need to install the [Go language](https://golang.org/dl/). Please install the latest version, not the one that is listed here.
+
+First, you need to install the [Go language](https://golang.org/dl/). Please install the latest version, not the one that is listed here.
wget -N https://storage.googleapis.com/golang/go1.8.1.windows-amd64.msi
msiexec /i go1.8.1.windows-amd64.msi /passive /promptrestart
-Then you need to install [ProtocolBuffers 3.0.0-beta-3](https://github.com/google/protobuf/releases) or later. Use the windows release while no native cygwin protoc with version 3 is available yet.
+Then you need to install [ProtocolBuffers 3.0.0-beta-3](https://github.com/google/protobuf/releases) or later. Use the Windows release as no native Cygwin `protoc` with version 3 is available yet.
wget -N https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-win32.zip`
7z x protoc-3.2.0-win32.zip -o/usr/local/
-Then you need to setup your Go workspace. Create the workspace dir.
+Then you need to set up your Go workspace. Create the workspace dir.
mkdir /home/user/go
mkdir /home/user/go/bin
mkdir /home/user/go/pkg
mkdir /home/user/go/src
-From an elevated cmd.exe prompt set the GOPATH variable in windows and add the `$GOPATH/bin` directory to your path using `reg add` instead of `setx` because [setx can truncated your PATH variable to 1024 characters](https://encrypted.google.com/search?hl=en&q=setx%20truncates%20PATH%201024#safe=off&hl=en&q=setx+truncated+PATH+1024).
+From an elevated cmd.exe prompt set the GOPATH variable in Windows and add the `$GOPATH/bin` directory to your path using `reg add` instead of `setx` because [setx can truncate your PATH variable to 1024 characters](https://encrypted.google.com/search?hl=en&q=setx%20truncates%20PATH%201024#safe=off&hl=en&q=setx+truncated+PATH+1024).
setx GOPATH c:\path\to\your\cygwin\home\user\go /M
set pathkey="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment"
@@ -33,20 +38,20 @@ From an elevated cmd.exe prompt set the GOPATH variable in windows and add the `
Then `go get -u -v` the following packages:
- go get -u -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
- go get -u -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
- go get -u -v github.com/golang/protobuf/protoc-gen-go
+ go get -u -v github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
+ go get -u -v github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
+ go get -u -v google.golang.org/protobuf/cmd/protoc-gen-go
+ go get -u -v google.golang.org/grpc/cmd/protoc-gen-go-grpc
-This will probably fail with similar output.
+This will probably fail with a similar output to this:
github.com/grpc-ecosystem/grpc-gateway (download)
# cd .; git clone https://github.com/grpc-ecosystem/grpc-gateway C:\path\to\your\cygwin\home\user\go\src\github.com\grpc-ecosystem\grpc-gateway
Cloning into 'C:\path\to\your\cygwin\home\user\go\src\github.com\grpc-ecosystem\grpc-gateway'...
fatal: Invalid path '/home/user/go/C:\path\to\your\cygwin\home\user\go\src\github.com\grpc-ecosystem\grpc-gateway': No such file or directory
- package github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway: exit status 128
+ package github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway: exit status 128
-To fix this you need to run the `go get -u -v` commands and look for all lines starting with `# cd .; `.
-Copy and paste these lines into your shell and change the clone destination directories.
+To fix this you need to run the `go get -u -v` commands and look for all lines starting with `# cd .;`. Copy and paste these lines into your shell and change the clone destination directories.
git clone https://github.com/grpc-ecosystem/grpc-gateway $(cygpath -u $GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway
git clone https://github.com/golang/glog $(cygpath -u $GOPATH)/src/github.com/golang/glog
@@ -56,19 +61,20 @@ Copy and paste these lines into your shell and change the clone destination dire
Once the clone operations are finished the `go get -u -v` commands shouldn't give you an error anymore.
## Usage
-Follow the [instuctions](https://github.com/grpc-ecosystem/grpc-gateway#usage) in the [README](https://github.com/grpc-ecosystem/grpc-gateway).
-Adjust steps 3, 5 and 7 like this. protoc expects native windows paths.
+Follow the [instructions](https://github.com/grpc-ecosystem/grpc-gateway#usage) in the [README](https://github.com/grpc-ecosystem/grpc-gateway#readme).
- protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. ./path/to/your_service.proto
- protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=logtostderr=true:. ./path/to/your_service.proto
- protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --swagger_out=logtostderr=true:. ./path/to/your_service.proto
+Adjust steps 3, 5 and 7 like this. `protoc` expects native Windows paths.
-Then `cd` into the directory where your entry-point `main.go` file is located and run
+ protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src --go_out=. --go-grpc_out=. ./path/to/your_service.proto
+ protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src --grpc-gateway_out=logtostderr=true:. ./path/to/your_service.proto
+ protoc -I. -I$(cygpath -w /usr/local/include) -I${GOPATH}/src --openapiv2_out=logtostderr=true:. ./path/to/your_service.proto
+
+Then `cd` into the directory where your entry-point `main.go` file is located and run:
go get -v
-This will fail like during the Installation. Look for all lines starting with `# cd .; ` and copy and paste these lines into your shell and change the clone destination directories.
+This will fail in this same way as it did during the installation. Look for all lines starting with `# cd .;`. Copy and paste these lines into your shell and change the clone destination directories.
git clone https://go.googlesource.com/net $(cygpath -u $GOPATH)/src/golang.org/x/net
git clone https://go.googlesource.com/text $(cygpath -u $GOPATH)/src/golang.org/x/text
@@ -76,8 +82,8 @@ This will fail like during the Installation. Look for all lines starting with `#
Once the clone operations are finished the `go get -v` commands shouldn't give you an error anymore.
-Then run
+Then run:
go install
-
-to compile and install your grpc-gateway service into `$GOPATH/bin`.
+
+This will compile and install your gRPC-Gateway service into `$GOPATH/bin`.
diff --git a/docs/docs/faq.md b/docs/docs/faq.md
new file mode 100644
index 00000000000..3d05c861a44
--- /dev/null
+++ b/docs/docs/faq.md
@@ -0,0 +1,64 @@
+---
+layout: default
+title: FAQ
+nav_order: 7
+---
+
+# FAQ
+
+## How can I write the annotations which gRPC-Gateway requires?
+
+The gRPC-Gateway follows the spec of [`google.api.HttpRule`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto), so first check out the documentation if it is feasible in the spec.
+
+For situations where annotating the proto file is not an option please reference the documentation on [gRPC API Configuration](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/grpc_api_configuration/)
+
+See also [a past discussion](https://groups.google.com/d/msg/grpc-io/Xqx80hG0D44/VNCDHjeE6pUJ) in the grpc-io mailing list.
+
+## I want to support a certain style of HTTP request but the code generated by gRPC-Gateway does not. How can I support this style?
+
+See the question above at first.
+
+The gRPC-Gateway is intended to cover 80% of use cases without forcing you to write comprehensive but complicated annotations. So the gateway itself does not always cover all the use cases you have by design. In other words, the gateway automates typical boring boilerplate mapping between gRPC and HTTP/1 communication, but it does not do arbitrarily complex custom mappings for you.
+
+On the other hand, you can still add whatever you want as a middleware which wraps
+[`runtime.ServeMux`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#ServeMux). Since `runtime.ServeMux` is just a standard [`http.Handler`](http://golang.org/pkg/http#Handler), you can easily write a custom wrapper of `runtime.ServeMux`, leveraged with existing third-party libraries in Go (e.g. [gateway main.go program](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/gateway/main.go).
+
+## My gRPC server is written in (Scala or C++ or Ruby or Haskell etc). Is there a (Scala or C++ or Ruby or Haskell etc) version of gRPC-Gateway?
+
+As of now, No. But it should not be a big issue because the reverse-proxy which gRPC-Gateway generates usually works as an independent process and communicates with your gRPC server over TCP or a Unix domain sockets (Unix systems only).
+
+## Why are the models in the OpenAPI specification prefixed with the last part of the proto package name?
+
+The reason to generate the prefixes is that we don't have a guaranteed unique namespace. If two packages produce different `Foo` messages then we will have trouble.
+
+## Why not strip the prefix?
+
+When a message is added which happens to conflict with another message (e.g. by importing a message with the same name from a different package) it will break code that is very far away from the code that changed. This is in an effort to adhere to the [principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment).
+
+## What is the difference between the gRPC-Gateway and grpc-httpjson-transcoding?
+
+The gRPC-Gateway is a generator that generates a Go implementation of a JSON/HTTP-gRPC reverse proxy based on annotations in your proto file, while the [grpc-httpjson-transcoding](https://github.com/grpc-ecosystem/grpc-httpjson-transcoding) library doesn't require the generation step, it uses protobuf descriptors as config. It can be used as a component of an existing proxy. Google Cloud Endpoints and the gRPC-JSON transcoder filter in Envoy are using this.
+
+
+**Behavior differences:**
+- By default, gRPC-Gateway does not escape path parameters in the same way. [This can be configured.](../mapping/customizing_your_gateway.md#Controlling-path-parameter-unescaping)
+
+## What is the difference between the gRPC-Gateway and gRPC-web?
+
+### Usage
+
+In the gRPC-Gateway, we generate a reverse-proxy from the proto file annotations. In the front-end, we call directly through REST APIs. We can generate an OpenAPI v2 specification that may further be used to generate the frontend client from using `protoc-gen-openapiv2`.
+
+In gRPC-web, the client code is generated directly from the proto files and can be used in the frontend.
+
+### Performance
+
+The gRPC-Gateway parses JSON to the protobuf binary format before sending it to the gRPC server. It then has to parse the reply back from the protobuf binary format to JSON again The parsing overhead has a negative impact on performance.
+
+In gRPC-web, the message is sent in the protobuf binary format already, so there is no additional parsing cost on the proxy side.
+
+### Maintenance
+
+With the gRPC-Gateway, if your proto file changes, we have to regenerate the gateway reverse proxy code. If you are using the HTTP/JSON interface you probably have to change the front-end too, which means making changes in two places.
+
+In gRPC-web, regenerating the files from the proto file will automatically update the front-end client.
diff --git a/docs/docs/mapping/binary_file_uploads.md b/docs/docs/mapping/binary_file_uploads.md
new file mode 100644
index 00000000000..1a378cf8fe0
--- /dev/null
+++ b/docs/docs/mapping/binary_file_uploads.md
@@ -0,0 +1,54 @@
+---
+layout: default
+title: Binary file uploads
+nav_order: 2
+parent: Mapping
+---
+
+# Binary file uploads
+
+If you need to do a binary file upload, e.g. via;
+
+```sh
+curl -X POST -F "attachment=@/tmp/somefile.txt" http://localhost:9090/v1/files
+```
+
+then your request will contain the binary data directly and there is no way to model this using gRPC.
+
+What you can do instead is to add a custom route directly on the `mux` instance.
+
+## Custom route on a mux instance
+
+Here we'll setup a handler (`handleBinaryFileUpload`) for `POST` requests:
+
+```go
+// Create a mux instance
+mux := runtime.NewServeMux()
+
+// Attachment upload from http/s handled manually
+mux.HandlePath("POST", "/v1/files", handleBinaryFileUpload)
+```
+
+And then in your handler you can do something like:
+
+```go
+func handleBinaryFileUpload(w http.ResponseWriter, r *http.Request, params map[string]string) {
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, fmt.Sprintf("failed to parse form: %s", err.Error()), http.StatusBadRequest)
+ return
+ }
+
+ f, header, err := r.FormFile("attachment")
+ if err != nil {
+ http.Error(w, fmt.Sprintf("failed to get file 'attachment': %s", err.Error()), http.StatusBadRequest)
+ return
+ }
+ defer f.Close()
+
+ //
+ // Now do something with the io.Reader in `f`, i.e. read it into a buffer or stream it to a gRPC client side stream.
+ // Also `header` will contain the filename, size etc of the original file.
+ //
+}
+```
diff --git a/docs/docs/mapping/customizing_openapi_output.md b/docs/docs/mapping/customizing_openapi_output.md
new file mode 100644
index 00000000000..a93828a508b
--- /dev/null
+++ b/docs/docs/mapping/customizing_openapi_output.md
@@ -0,0 +1,826 @@
+---
+layout: default
+title: Customizing OpenAPI Output
+nav_order: 4
+parent: Mapping
+---
+
+{% raw %}
+
+# Customizing OpenAPI Output
+
+## In proto comments
+
+You can provide comments directly in your Protocol Buffer definitions and they will be translated into comments in the generated OpenAPI definitions:
+
+```protobuf
+message MyMessage {
+ // This comment will end up direcly in your Open API definition
+ string uuid = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "The UUID field."}];
+}
+```
+
+## Using proto options
+
+You can define options on your Protocol Buffer services, operations, messages, and field definitions to customize your Open API output. For instance, to customize the [OpenAPI Schema Object](https://swagger.io/specification/v2/#schemaObject) for messages and fields:
+
+```protobuf
+import "protoc-gen-openapiv2/options/annotations.proto";
+
+message ABitOfEverything {
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
+ json_schema: {
+ title: "A bit of everything"
+ description: "Intentionaly complicated message type to cover many features of Protobuf."
+ required: ["uuid", "int64_value", "double_value"]
+ }
+ external_docs: {
+ url: "https://github.com/grpc-ecosystem/grpc-gateway";
+ description: "Find out more about ABitOfEverything";
+ }
+ example: "{\"uuid\": \"0cf361e1-4b44-483d-a159-54dabdf7e814\"}"
+ extensions: {
+ key: "x-irreversible";
+ value {
+ bool_value: true;
+ }
+ }
+ };
+
+ string uuid = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "The UUID field."}];
+}
+```
+
+Operations can also be customized:
+
+```protobuf
+service ABitOfEverythingService {
+ rpc Delete(grpc.gateway.examples.internal.proto.sub2.IdMessage) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ delete: "/v1/example/a_bit_of_everything/{uuid}"
+ };
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+ security: {
+ security_requirement: {
+ key: "ApiKeyAuth";
+ value: {}
+ }
+ security_requirement: {
+ key: "OAuth2";
+ value: {
+ scope: "read";
+ scope: "write";
+ }
+ }
+ }
+ extensions: {
+ key: "x-irreversible";
+ value {
+ bool_value: true;
+ }
+ }
+ };
+ }
+}
+```
+
+[Swagger Extensions](https://swagger.io/docs/specification/2-0/swagger-extensions/) can be added as key-value pairs to the options. Keys must begin with `x-` and values can be of any type listed [here](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#value). For example:
+```
+extensions: {
+ key: "x-amazon-apigateway-authorizer";
+ value {
+ struct_value {
+ fields {
+ key: "type";
+ value {
+ string_value: "token";
+ }
+ }
+ fields {
+ key: "authorizerResultTtlInSeconds";
+ value {
+ number_value: 60;
+ }
+ }
+ }
+ }
+}
+```
+
+Please see this [a_bit_of_everything.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto) for examples of the options being used.
+
+## Using google.api.field_behavior
+
+Google provides an [field option](https://github.com/googleapis/googleapis/blob/master/google/api/field_behavior.proto) for defining the behavior of fields that is also supported:
+
+```protobuf
+import "google/api/field_behavior.proto";
+
+message MyMessage {
+ string a_required_field = 1 [(google.api.field_behavior) = REQUIRED];
+}
+```
+
+The following options are used in the Open API output:
+
+- `REQUIRED` - marks a field as required
+- `OUTPUT_ONLY` - marks a field as readonly
+
+Google defines a couple of other options - `OPTIONAL`, `IMMUTABLE`, `INPUT_ONLY` -
+that are not currently used. `OPTIONAL` support is currently under discussion
+in [this issue](https://github.com/grpc-ecosystem/grpc-gateway/issues/669).
+
+For `IMMUTABLE` and `INPUT_ONLY` fields, there is an [open issue](https://github.com/OAI/OpenAPI-Specification/issues/1497) in the Open API specification for adding functionality for write-once or immutable fields to the spec.
+## Using go templates in proto file comments
+
+Use [Go templates](https://golang.org/pkg/text/template/) in your proto file comments to allow more advanced documentation such as:
+
+- Documentation about fields in the proto objects.
+- Import the content of external files (such as
+ [Markdown](https://en.wikipedia.org/wiki/Markdown)).
+
+### How to use it
+
+By default this function is turned off, so if you want to use it you have to add the `use_go_templates` option:
+
+```sh
+--openapiv2_out . --openapiv2_opt use_go_templates=true
+```
+
+or:
+
+```sh
+--openapiv2_out=use_go_templates=true:.
+```
+
+#### Example script
+
+Example of a bash script with the `use_go_templates` flag set to true:
+
+```sh
+$ protoc -I. \
+ --go_out . --go-grpc_out . \
+ --grpc-gateway_out . --grpc-gateway_opt logtostderr=true \
+ --openapiv2_out . \
+ --openapiv2_opt logtostderr=true \
+ --openapiv2_opt use_go_templates=true \
+ path/to/my/proto/v1/myproto.proto
+```
+
+#### Example proto file
+
+Example of a proto file with Go templates. This proto file imports documentation from another file, `tables.md`:
+
+```protobuf
+service LoginService {
+ // Login
+ //
+ // {{.MethodDescriptorProto.Name}} is a call with the method(s) {{$first := true}}{{range .Bindings}}{{if $first}}{{$first = false}}{{else}}, {{end}}{{.HTTPMethod}}{{end}} within the "{{.Service.Name}}" service.
+ // It takes in "{{.RequestType.Name}}" and returns a "{{.ResponseType.Name}}".
+ //
+ // {{import "tables.md"}}
+ rpc Login (LoginRequest) returns (LoginReply) {
+ option (google.api.http) = {
+ post: "/v1/example/login"
+ body: "*"
+ };
+ }
+}
+
+message LoginRequest {
+ // The entered username
+ string username = 1;
+ // The entered password
+ string password = 2;
+}
+
+message LoginReply {
+ // Whether you have access or not
+ bool access = 1;
+}
+```
+
+The content of `tables.md`:
+
+```markdown
+## {{.RequestType.Name}}
+| Field ID | Name | Type | Description |
+| ----------- | --------- | --------------------------------------------------------- | ---------------------------- | {{range .RequestType.Fields}}
+| {{.Number}} | {{.Name}} | {{if eq .Label.String "LABEL_REPEATED"}}[]{{end}}{{.Type}} | {{fieldcomments .Message .}} | {{end}}
+
+## {{.ResponseType.Name}}
+| Field ID | Name | Type | Description |
+| ----------- | --------- | ---------------------------------------------------------- | ---------------------------- | {{range .ResponseType.Fields}}
+| {{.Number}} | {{.Name}} | {{if eq .Label.String "LABEL_REPEATED"}}[]{{end}}{{.Type}} | {{fieldcomments .Message .}} | {{end}}
+```
+
+### OpenAPI output
+
+#### SwaggerUI
+
+This is how the OpenAPI file would be rendered in [Swagger UI](https://swagger.io/tools/swagger-ui/).
+
+
+
+#### Postman
+
+This is how the OpenAPI file would be rendered in [Postman](https://www.getpostman.com/).
+
+
+
+For a more detailed example of a proto file that has Go, templates enabled, [see the examples](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/use_go_template.proto).
+
+## Other plugin options
+
+A comprehensive list of OpenAPI plugin options can be found [here](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/main.go). Options can be passed via `protoc` CLI:
+
+```sh
+--openapiv2_out . --openapiv2_opt bar=baz,color=red
+```
+
+Or, with `buf` in `buf.gen.yaml`:
+
+```yaml
+ - name: openapiv2
+ out: foo
+ opt: bar=baz,color=red
+```
+
+### Merging output
+
+If your protobuf definitions are spread across multiple files, the OpenAPI plugin will create a file for each `.proto` input. This may make sense for Go bindings, since they still share a package space, but fragmenting OpenAPI specifications across multiple files changes the schema itself.
+
+To merge disparate `.proto` inputs into a single OpenAPI file, use the `allow_merge` and `merge_file_name` options.
+
+`opt: allow_merge=true,merge_file_name=foo` will result in a single `foo.swagger.json`. Note that you may need to set
+the [generation strategy](https://docs.buf.build/configuration/v1/buf-gen-yaml/#strategy) to `all` when merging many files:
+
+```yaml
+ - name: openapiv2
+ out: foo
+ strategy: all
+ opt: allow_merge=true,merge_file_name=foo
+```
+
+### Enums as integers
+
+To generate enums as integers instead of strings, use `enums_as_ints`.
+
+`opt: enums_as_ints=true` will result in:
+
+
+```json
+{
+ "name": "enumValue",
+ "description": " - Example enums",
+ "in": "query",
+ "required": false,
+ "type": "int",
+ "enum": [
+ 0,
+ 1
+ ],
+ "default": 0
+},
+```
+
+### Omitting the default value of enums
+
+If you define enum types with non default value such as declaring 0 value with UNKNOWN and want to omit the default value from generated swagger file, use `omit_enum_default_value`.
+This option also applies if enums_as_ints option is enalbled to generate enums as integer.
+
+`opt: omit_enum_default_value=true` will result in:
+
+Input Example:
+```
+enum enumValue {
+ UNKNOWN = 0;
+ FOO = 1;
+}
+```
+
+Output json:
+```json
+{
+ "name": "enumValue",
+ "description": " - Example enums",
+ "in": "query",
+ "required": false,
+ "type": "string",
+ "enum": [
+ "FOO"
+ ]
+},
+```
+
+### Hiding fields, methods, services and enum values
+
+If you require internal or unreleased fields and APIs to be hidden from your API documentation, [`google.api.VisibilityRule`](https://github.com/googleapis/googleapis/blob/9916192ab15e3507e41ba2c5165182fec06120d0/google/api/visibility.proto#L89) annotations can be added to customize where they are generated. Combined with the option `visibility_restriction_selectors`, overlapping rules will appear in the OpenAPI output.
+
+`visibility_restriction_selectors` can be declared multiple times as an option to include multiple visibility restrictions in the output.
+e.g. if you are using `buf`:
+
+```yaml
+version: v1
+plugins:
+ - name: openapiv2
+ out: .
+ opt:
+ - visibility_restriction_selectors=PREVIEW
+ - visibility_restriction_selectors=INTERNAL
+```
+
+or with `protoc`
+
+```sh
+protoc --openapiv2_out=. --openapiv2_opt=visibility_restriction_selectors=PREVIEW --openapiv2_opt=visibility_restriction_selectors=INTERNAL ./path/to/file.proto
+```
+
+Elements without `google.api.VisibilityRule` annotations will appear as usual in the generated output.
+
+These restrictions and selectors are completely arbitrary and you can define whatever values or hierarchies you want. In this example we use `INTERNAL` and `PREVIEW`, but `INTERNAL`, `ALPHA`, `BETA`, `RELEASED`, or anything else could be used if you wish.
+
+Note: Annotations are only supported on Services, Methods, Fields and Enum Values.
+
+`opt: visibility_restriction_selectors=PREVIEW` will result in:
+
+Input Example:
+```protobuf
+service Echo {
+ rpc EchoInternal(VisibilityRuleSimpleMessage) returns (VisibilityRuleSimpleMessage) {
+ option (google.api.method_visibility).restriction = "INTERNAL";
+ option (google.api.http) = {
+ get: "/v1/example/echo_internal"
+ };
+ }
+ rpc EchoInternalAndPreview(VisibilityRuleSimpleMessage) returns (VisibilityRuleSimpleMessage) {
+ option (google.api.method_visibility).restriction = "INTERNAL,PREVIEW";
+ option (google.api.http) = {
+ get: "/v1/example/echo_internal_and_preview"
+ };
+ }
+}
+
+message VisibilityRuleSimpleMessage {
+ enum VisibilityEnum {
+ UNSPECIFIED = 0;
+ VISIBLE = 1;
+ INTERNAL = 2 [(google.api.value_visibility).restriction = "INTERNAL"];
+ PREVIEW = 3 [(google.api.value_visibility).restriction = "INTERNAL,PREVIEW"];
+ }
+
+ string internal_field = 1 [(google.api.field_visibility).restriction = "INTERNAL"];
+ string preview_field = 2 [(google.api.field_visibility).restriction = "INTERNAL,PREVIEW"];
+ VisibilityEnum an_enum = 3;
+}
+```
+
+Output json:
+```json
+{
+ "paths": {
+ "/v1/example/echo_internal_and_preview": {
+ "get": {
+ "summary": "EchoInternalAndPreview is a internal and preview API that should be visible in the OpenAPI spec.",
+ "operationId": "VisibilityRuleEchoService_EchoInternalAndPreview",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/examplepbVisibilityRuleSimpleMessage"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "previewField",
+ "in": "query",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "anEnum",
+ "in": "query",
+ "required": false,
+ "type": "string",
+ "enum": [
+ "UNSPECIFIED",
+ "VISIBLE",
+ "PREVIEW"
+ ],
+ "default": "UNSPECIFIED"
+ }
+ ],
+ "tags": [
+ "VisibilityRuleEchoService"
+ ]
+ }
+ }
+ }
+}
+```
+
+For a more in depth example see [visibility_rule_echo_service.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/visibility_rule_echo_service.proto) and the following output files for different values of `visibility_restriction_selectors`:
+- [`visibility_restriction_selectors=PREVIEW`](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/visibility_rule_preview_echo_service.swagger.json)
+- [`visibility_restriction_selectors=INTERNAL`](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/visibility_rule_internal_echo_service.swagger.json)
+- [`visibility_restriction_selectors=INTERNAL,visibility_restriction_selectors=PREVIEW`](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/visibility_rule_preview_and_internal_echo_service.swagger.json)
+- [Not set](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/visibility_rule_none_echo_service.swagger.json)
+
+### Path parameters
+
+When defining HTTP bindings with path parameters that contain multiple path segments, as suggested by the [Google AIPs](https://google.aip.dev/), the path parameter names are numbered to avoid generating duplicate paths in the OpenAPI file.
+
+For example, consider:
+```protobuf
+service LibraryService {
+ rpc GetShelf(GetShelfRequest) returns (Shelf) {
+ option (google.api.http) = {
+ get: "/v1/{name=shelves/*}"
+ };
+ }
+ rpc GetBook(GetBookRequest) returns (Book) {
+ option (google.api.http) = {
+ get: "/v1/{name=shelves/*/books/*}"
+ };
+ }
+}
+
+message GetShelfRequest {
+ string name = 1;
+}
+
+message GetBookRequest {
+ string name = 1;
+}
+```
+
+This will generate the following paths:
+- `/v1/{name}`
+- `/v1/{name_1}`
+
+To override the path parameter names, annotate the field used as path parameter:
+```protobuf
+message GetShelfRequest {
+ string name = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {field_configuration: {path_param_name: "shelfName"}}];
+}
+message GetBookRequest {
+ string name = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {field_configuration: {path_param_name: "bookName"}}];
+}
+```
+
+This will instead generate the following paths:
+- `/v1/{shelfName}`
+- `/v1/{bookName}`
+
+Note that path parameters in OpenAPI does not support values with `/`, as discussed in
+[Support for path parameters which can contain slashes #892](https://github.com/OAI/OpenAPI-Specification/issues/892),
+so tools as Swagger UI will URL encode any `/` provided as parameter value. A possible workaround for this is to write
+a custom post processor for your OAS file to replace any path parameter with `/` into multiple parameters.
+
+### Output format
+
+By default the output format is JSON, but it is possible to configure it using the `output_format` option. Allowed values are: `json`, `yaml`. The output format will also change the extension of the output files.
+
+For example, if using `buf`:
+```yaml
+ - name: openapiv2
+ out: pkg
+ opt: output_format=yaml
+```
+
+Input example:
+```protobuf
+syntax = "proto3";
+
+package helloproto.v1;
+option go_package = "helloproto/v1;helloproto";
+
+import "google/api/annotations.proto";
+
+service EchoService {
+ rpc Hello(HelloReq) returns (HelloResp) {
+ option (google.api.http) = {
+ get: "/api/hello"
+ };
+ }
+}
+
+message HelloReq {
+ string name = 1;
+}
+
+message HelloResp {
+ string message = 1;
+}
+```
+
+Output:
+```yaml
+swagger: "2.0"
+info:
+ title: helloproto/v1/example.proto
+ version: version not set
+tags:
+- name: EchoService
+consumes:
+- application/json
+produces:
+- application/json
+paths:
+ /api/hello:
+ get:
+ operationId: EchoService_Hello
+ responses:
+ "200":
+ description: A successful response.
+ schema:
+ $ref: '#/definitions/v1HelloResp'
+ default:
+ description: An unexpected error response.
+ schema:
+ $ref: '#/definitions/rpcStatus'
+ parameters:
+ - name: name
+ in: query
+ required: false
+ type: string
+ tags:
+ - EchoService
+definitions:
+ protobufAny:
+ type: object
+ properties:
+ '@type':
+ type: string
+ additionalProperties: {}
+ rpcStatus:
+ type: object
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
+ details:
+ type: array
+ items:
+ $ref: '#/definitions/protobufAny'
+ v1HelloResp:
+ type: object
+ properties:
+ message:
+ type: string
+```
+
+### Disable service tag generation
+
+By default service tags are generated for backend services, but it is possible to disable it using the `disable_service_tags` option. Allowed values are: `true`, `false`.
+
+For example, if you are using `buf`:
+```yaml
+version: v1
+plugins:
+ - name: openapiv2
+ out: .
+ opt:
+ - disable_service_tags=true
+```
+
+or with `protoc`
+
+```sh
+protoc --openapiv2_out=. --openapiv2_opt=disable_service_tags=true ./path/to/file.proto
+```
+
+Input example:
+```protobuf
+syntax = "proto3";
+
+package helloproto.v1;
+option go_package = "helloproto/v1;helloproto";
+
+import "google/api/annotations.proto";
+
+service EchoService {
+ rpc Hello(HelloReq) returns (HelloResp) {
+ option (google.api.http) = {
+ get: "/api/hello"
+ };
+ }
+}
+
+message HelloReq {
+ string name = 1;
+}
+
+message HelloResp {
+ string message = 1;
+}
+```
+
+Output (tags object are not generated):
+```yaml
+swagger: "2.0"
+info:
+ title: helloproto/v1/example.proto
+ version: version not set
+consumes:
+ - application/json
+produces:
+ - application/json
+paths:
+ /api/hello:
+ get:
+ operationId: EchoService_Hello
+```
+
+### Disable default responses
+
+By default a 200 OK response is rendered for each service operation. But it is possible to disable this and explicitly define your service's responses, using the `disable_default_responses` option. Allowed values are: `true`, `false`.
+
+**Note**: This does not alter the behavior of the gateway itself and should be coupled with a `ForwardResponseWriter` when altering status codes, see [Controlling HTTP Response Codes](https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_your_gateway/#controlling-http-response-status-codes).
+
+For example, if you are using `buf`:
+
+```yaml
+version: v1
+plugins:
+ - name: openapiv2
+ out: .
+ opt:
+ - disable_default_responses=true
+```
+
+or with `protoc`
+
+```sh
+protoc --openapiv2_out=. --openapiv2_opt=disable_default_responses=true ./path/to/file.proto
+```
+
+Input example:
+
+```protobuf
+syntax = "proto3";
+
+package helloproto.v1;
+
+import "google/api/annotations.proto";
+import "protoc-gen-openapiv2/options/annotations.proto";
+
+option go_package = "helloproto/v1;helloproto";
+
+service EchoService {
+ rpc Hello(HelloReq) returns (HelloResp) {
+ option (google.api.http) = {get: "/api/hello"};
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+ responses: {
+ key: "201",
+ value: {
+ description: "Created";
+ schema: {
+ json_schema: {ref: ".helloproto.v1.HelloResp"}
+ }
+ }
+ };
+ };
+ }
+}
+
+message HelloReq {
+ string name = 1;
+}
+
+message HelloResp {
+ string message = 1;
+}
+```
+
+Output (default response not generated):
+
+```yaml
+swagger: "2.0"
+info:
+ title: helloproto/v1/hello.proto
+ version: version not set
+consumes:
+ - application/json
+produces:
+ - application/json
+paths:
+ /api/hello:
+ get:
+ operationId: EchoService_Hello
+ responses:
+ "201":
+ description: Created
+ schema:
+ $ref: "#/definitions/v1HelloResp"
+ parameters:
+ - name: name
+ in: query
+ required: false
+ type: string
+definitions:
+ v1HelloResp:
+ type: object
+ properties:
+ message:
+ type: string
+```
+
+### Custom HTTP Header Request Parameters
+
+By default the parameters for each operation are generated from the protocol buffer definition however you can extend the parameters to include extra HTTP headers if required.
+
+**NOTE**: These annotations do not alter the behaviour of the gateway and must be coupled with custom header parsing behaviour in the application. Also be aware that adding header parameters can alter the forwards and backwards compatibility of the schema. You must also set a type for your header which can be one of `STRING`, `INTEGER`, `NUMBER` or `BOOLEAN`.
+
+```protobuf
+syntax = "proto3";
+
+package helloproto.v1;
+
+import "google/api/annotations.proto";
+import "protoc-gen-openapiv2/options/annotations.proto";
+
+option go_package = "helloproto/v1;helloproto";
+
+service EchoService {
+ rpc Hello(HelloReq) returns (HelloResp) {
+ option (google.api.http) = {get: "/api/hello"};
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+ parameters: {
+ headers: {
+ name: "X-Foo";
+ description: "Foo Header";
+ type: STRING,
+ required: true;
+ };
+ headers: {
+ name: "X-Bar";
+ description: "Bar Header";
+ type: NUMBER,
+ };
+ };
+ };
+ }
+}
+
+message HelloReq {
+ string name = 1;
+}
+
+message HelloResp {
+ string message = 1;
+}
+```
+
+Output:
+
+```yaml
+swagger: "2.0"
+info:
+ title: helloproto/v1/hello.proto
+ version: version not set
+consumes:
+ - application/json
+produces:
+ - application/json
+paths:
+ /api/hello:
+ get:
+ operationId: Hello
+ responses:
+ "200":
+ description: A successful response.
+ schema:
+ $ref: "#/definitions/helloproto.v1.HelloResp"
+ parameters:
+ - name: name
+ in: query
+ required: false
+ type: string
+ - name: X-Foo
+ description: Foo Header
+ in: header
+ required: true
+ type: string
+ - name: X-Bar
+ description: Bar Header
+ in: header
+ required: false
+ type: number
+definitions:
+ helloproto.v1.HelloResp:
+ type: object
+ properties:
+ message:
+ type: string
+```
+
+{% endraw %}
diff --git a/docs/docs/mapping/customizing_your_gateway.md b/docs/docs/mapping/customizing_your_gateway.md
new file mode 100644
index 00000000000..ca09c8c9d21
--- /dev/null
+++ b/docs/docs/mapping/customizing_your_gateway.md
@@ -0,0 +1,412 @@
+---
+layout: default
+title: Customizing your gateway
+nav_order: 5
+parent: Mapping
+---
+
+# Customizing your gateway
+
+## Message serialization
+
+### Custom serializer
+
+You might want to serialize request/response messages in MessagePack instead of JSON, for example:
+
+1. Write a custom implementation of [`Marshaler`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#Marshaler).
+
+2. Register your marshaler with [`WithMarshalerOption`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#WithMarshalerOption).
+
+ e.g.
+
+ ```go
+ var m your.MsgPackMarshaler
+ mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption("application/x-msgpack", m),
+ )
+ ```
+
+You can see [the default implementation for JSON](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/marshal_jsonpb.go) for reference.
+
+### Using proto names in JSON
+
+The protocol buffer compiler generates camelCase JSON tags that are used by default.
+If you want to use the exact case used in the proto files, set `UseProtoNames: true`:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ UseProtoNames: true,
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ }),
+)
+```
+
+### Pretty-print JSON responses when queried with ?pretty
+
+You can have Elasticsearch-style `?pretty` support in your gateway's endpoints as follows:
+
+1. Wrap the ServeMux using a stdlib [`http.HandlerFunc`](https://golang.org/pkg/net/http/#HandlerFunc) that translates the provided query parameter into a custom `Accept` header.
+
+2. Register a pretty-printing marshaler for that MIME code.
+
+For example:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption("application/json+pretty", &runtime.JSONPb{
+ MarshalOptions: protojson.MarshalOptions{
+ Indent: " ",
+ Multiline: true, // Optional, implied by presence of "Indent".
+ },
+ UnmarshalOptions: protojson.UnmarshalOptions{
+ DiscardUnknown: true,
+ },
+ }),
+)
+prettier := func(h http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // checking Values as map[string][]string also catches ?pretty and ?pretty=
+ // r.URL.Query().Get("pretty") would not.
+ if _, ok := r.URL.Query()["pretty"]; ok {
+ r.Header.Set("Accept", "application/json+pretty")
+ }
+ h.ServeHTTP(w, r)
+ })
+}
+http.ListenAndServe(":8080", prettier(mux))
+```
+
+Now, either when passing the header `Accept: application/json+pretty` or appending `?pretty` to your HTTP endpoints, the response will be pretty-printed.
+
+Note that this will conflict with any methods having input messages with fields named `pretty`; also, this example code does not remove the query parameter `pretty` from further processing.
+
+## Customize unmarshaling per Content-Type
+
+Having different unmarshaling options per Content-Type is as easy as configuring a custom marshaler:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMarshalerOption("application/json+strict", &runtime.JSONPb{
+ UnmarshalOptions: &protojson.UnmarshalOptions{
+ DiscardUnknown: false, // explicit "false", &protojson.UnmarshalOptions{} would have the same effect
+ },
+ }),
+)
+```
+
+## Mapping from HTTP request headers to gRPC client metadata
+
+You might not like [the default mapping rule](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#DefaultHeaderMatcher) and might want to pass through all the HTTP headers, for example:
+
+1. Write a [`HeaderMatcherFunc`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#HeaderMatcherFunc).
+
+2. Register the function with [`WithIncomingHeaderMatcher`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#WithIncomingHeaderMatcher)
+
+ e.g.
+
+ ```go
+ func CustomMatcher(key string) (string, bool) {
+ switch key {
+ case "X-Custom-Header1":
+ return key, true
+ case "X-Custom-Header2":
+ return "custom-header2", true
+ default:
+ return key, false
+ }
+ }
+
+ mux := runtime.NewServeMux(
+ runtime.WithIncomingHeaderMatcher(CustomMatcher),
+ )
+ ```
+
+To keep the [the default mapping rule](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#DefaultHeaderMatcher) alongside with your own rules write:
+
+```go
+func CustomMatcher(key string) (string, bool) {
+ switch key {
+ case "X-User-Id":
+ return key, true
+ default:
+ return runtime.DefaultHeaderMatcher(key)
+ }
+}
+```
+
+It will work with both:
+
+```sh
+$ curl --header "x-user-id: 100d9f38-2777-4ee2-ac3b-b3a108f81a30" ...
+```
+
+and
+
+```sh
+$ curl --header "X-USER-ID: 100d9f38-2777-4ee2-ac3b-b3a108f81a30" ...
+```
+
+To access this header on gRPC server side use:
+
+```go
+userID := ""
+if md, ok := metadata.FromIncomingContext(ctx); ok {
+ if uID, ok := md["x-user-id"]; ok {
+ userID = strings.Join(uID, ",")
+ }
+}
+```
+
+## Mapping from gRPC server metadata to HTTP response headers
+
+Use [`WithOutgoingHeaderMatcher`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#WithOutgoingHeaderMatcher). See [gRPC metadata docs](https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md) for more info on sending / receiving gRPC metadata, for example:
+
+```go
+if appendCustomHeader {
+ grpc.SendHeader(ctx, metadata.New(map[string]string{
+ "x-custom-header1": "value",
+ }))
+}
+```
+
+## Mutate response messages or set response headers
+
+### Set HTTP headers
+
+You might want to return a subset of response fields as HTTP response headers; You might want to simply set an application-specific token in a header. Or you might want to mutate the response messages to be returned.
+
+1. Write a filter function.
+
+```go
+func myFilter(ctx context.Context, w http.ResponseWriter, resp proto.Message) error {
+ t, ok := resp.(*externalpb.Tokenizer)
+ if ok {
+ w.Header().Set("X-My-Tracking-Token", t.Token)
+ t.Token = ""
+ }
+ return nil
+}
+```
+
+2. Register the filter with [`WithForwardResponseOption`](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#WithForwardResponseOption)
+
+e.g.
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithForwardResponseOption(myFilter),
+)
+```
+
+### Controlling HTTP response status codes
+
+To have the most control over the HTTP response status codes, you can use custom metadata.
+
+While handling the rpc, set the intended status code:
+
+```go
+_ = grpc.SetHeader(ctx, metadata.Pairs("x-http-code", "401"))
+```
+
+Now, before sending the HTTP response, we need to check for this metadata pair and explicitly set the status code for the response if found.
+To do so, create a function and hook it into the gRPC-Gateway as a Forward Response Option.
+
+The function looks like this:
+
+```go
+func httpResponseModifier(ctx context.Context, w http.ResponseWriter, p proto.Message) error {
+ md, ok := runtime.ServerMetadataFromContext(ctx)
+ if !ok {
+ return nil
+ }
+
+ // set http status code
+ if vals := md.HeaderMD.Get("x-http-code"); len(vals) > 0 {
+ code, err := strconv.Atoi(vals[0])
+ if err != nil {
+ return err
+ }
+ // delete the headers to not expose any grpc-metadata in http response
+ delete(md.HeaderMD, "x-http-code")
+ delete(w.Header(), "Grpc-Metadata-X-Http-Code")
+ w.WriteHeader(code)
+ }
+
+ return nil
+}
+```
+
+And it gets hooked into the gRPC-Gateway with:
+
+```go
+gwMux := runtime.NewServeMux(
+ runtime.WithForwardResponseOption(httpResponseModifier),
+)
+```
+
+Additional responses can be added to the Protocol Buffer definitions to match the new status codes:
+
+```protobuf
+service Greeter {
+ rpc SayHello (HelloRequest) returns (HelloReply) {
+ option (google.api.http) = {
+ post: "/v1/example/echo"
+ body: "*"
+ };
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+ responses: {
+ key: "201"
+ value: {
+ description: "A successful response."
+ schema: {
+ json_schema: {
+ ref: ".mypackage.HelloReply"
+ }
+ }
+ }
+ }
+ };
+ }
+
+ rpc SayGoodbye (GoodbyeRequest) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ delete: "/v1/example/echo/{id}"
+ };
+ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
+ responses: {
+ key: "204"
+ value: {
+ description: "A successful response."
+ schema: {}
+ }
+ }
+ };
+ }
+}
+```
+
+## Error handler
+
+To override error handling for a `*runtime.ServeMux`, use the
+`runtime.WithErrorHandler` option. This will configure all unary error
+responses to pass through this error handler.
+
+## Stream Error Handler
+
+The error handler described in the previous section applies only to RPC methods that have a unary response.
+
+When the method has a streaming response, gRPC-Gateway handles that by emitting a newline-separated stream of "chunks". Each chunk is an envelope that can contain either a response message or an error. Only the last chunk will include an error, and only when the RPC handler ends abnormally (i.e. with an error code).
+
+Because of the way the errors are included in the response body, the other error handler signature is insufficient. So for server streams, you must install a _different_ error handler:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithStreamErrorHandler(handleStreamError),
+)
+```
+
+The signature of the handler is much more rigid because we need to know the structure of the error payload to properly encode the "chunk" schema into an OpenAPI spec.
+
+So the function must return a `*runtime.StreamError`. The handler can choose to omit some fields and can filter/transform the original error, such as stripping stack traces from error messages.
+
+Here's an example custom handler:
+
+```go
+// handleStreamError overrides default behavior for computing an error
+// message for a server stream.
+//
+// It uses a default "502 Bad Gateway" HTTP code, only emits "safe"
+// messages and does not set the details field (so it will
+// be omitted from the resulting JSON object that is sent to client).
+func handleStreamError(ctx context.Context, err error) *status.Status {
+ code := codes.Internal
+ msg := "unexpected error"
+ if s, ok := status.FromError(err); ok {
+ code = s.Code()
+ // default message, based on the gRPC status
+ msg = s.Message()
+ // see if error details include "safe" message to send
+ // to external callers
+ for _, msg := range s.Details() {
+ if safe, ok := msg.(*SafeMessage); ok {
+ msg = safe.Text
+ break
+ }
+ }
+ }
+ return status.Errorf(code, msg)
+}
+```
+
+If no custom handler is provided, the default stream error handler will include any gRPC error attributes (code, message, detail messages), if the error being reported includes them. If the error does not have these attributes, a gRPC code of `Unknown` (2) is reported.
+
+## Controlling path parameter unescaping
+
+
+
+By default, gRPC-Gateway unescapes the entire URL path string attempting to route a request. This causes routing errors when the path parameter contains an illegal character such as `/`.
+
+To replicate the behavior described in [google.api.http](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L224), use [runtime.WithUnescapingMode()](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime?tab=doc#WithUnescapingMode) to configure the unescaping behavior, as in the example below:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithUnescapingMode(runtime.UnescapingModeAllExceptReserved),
+)
+```
+
+For multi-segment parameters (e.g. `{id=**}`) [RFC 6570](https://tools.ietf.org/html/rfc6570) Reserved Expansion characters are left escaped and the gRPC API will need to unescape them.
+
+To replicate the default V2 escaping behavior but also allow passing pct-encoded `/` characters, the ServeMux can be configured as in the example below:
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithUnescapingMode(runtime.UnescapingModeAllCharacters),
+)
+```
+
+## Routing Error handler
+
+To override the error behavior when `*runtime.ServeMux` was not able to serve the request due to routing issues, use the `runtime.WithRoutingErrorHandler` option.
+
+This will configure all HTTP routing errors to pass through this error handler. The default behavior is to map HTTP error codes to gRPC errors.
+
+HTTP statuses and their mappings to gRPC statuses:
+
+- HTTP `404 Not Found` -> gRPC `5 NOT_FOUND`
+- HTTP `405 Method Not Allowed` -> gRPC `12 UNIMPLEMENTED`
+- HTTP `400 Bad Request` -> gRPC `3 INVALID_ARGUMENT`
+
+This method is not used outside of the initial routing.
+
+### Customizing Routing Errors
+
+If you want to retain HTTP `405 Method Not Allowed` instead of allowing it to be converted to the equivalent of the gRPC `12 UNIMPLEMENTED`, which is HTTP `501 Not Implmented` you can use the following example:
+
+```go
+func handleRoutingError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) {
+ if httpStatus != http.StatusMethodNotAllowed {
+ runtime.DefaultRoutingErrorHandler(ctx, mux, marshaler, writer, request, httpStatus)
+ return
+ }
+
+ // Use HTTPStatusError to customize the DefaultHTTPErrorHandler status code
+ err := &HTTPStatusError{
+ HTTPStatus: httpStatus
+ Err: status.Error(codes.Unimplemented, http.StatusText(httpStatus))
+ }
+
+ runtime.DefaultHTTPErrorHandler(ctx, mux, marshaler, w , r, err)
+}
+```
+
+To use this routing error handler, construct the mux as follows:
+```go
+mux := runtime.NewServeMux(
+ runtime.WithRoutingErrorHandler(handleRoutingError),
+)
+```
diff --git a/docs/docs/mapping/examples.md b/docs/docs/mapping/examples.md
new file mode 100644
index 00000000000..48e8473164b
--- /dev/null
+++ b/docs/docs/mapping/examples.md
@@ -0,0 +1,27 @@
+---
+layout: default
+title: Examples
+nav_order: 0
+parent: Mapping
+---
+
+# Examples
+
+Examples are available under `examples/internal` directory.
+
+- [`proto/examplepb/echo_service.proto`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/echo_service.proto), [`proto/examplepb/a_bit_of_everything.proto`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/a_bit_of_everything.proto), [`proto/examplepb/unannotated_echo_service.proto`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.proto):
+ protobuf service definitions.
+- [`proto/examplepb/echo_service.pb.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/echo_service.pb.go), [`proto/examplepb/a_bit_of_everything.pb.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/a_bit_of_everything.pb.go), [`proto/examplepb/unannotated_echo_service.pb.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.pb.go):
+ generated Go service stubs and types.
+- [`proto/examplepb/echo_service.pb.gw.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/echo_service.pb.gw.go), [`proto/examplepb/a_bit_of_everything.pb.gw.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/a_bit_of_everything.pb.gw.go), [`proto/examplepb/unannotated_echo_service.pb.gw.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.pb.gw.go):
+ generated gRPC-Gateway clients.
+- [`proto/examplepb/unannotated_echo_service.yaml`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.yaml):
+ gRPC API Configuration for `unannotated_echo_service.proto`.
+- [`server/main.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/server/main.go):
+ service implementation.
+- [`main.go`](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/gateway/main.go):
+ entrypoint of the generated reverse proxy.
+
+To use the same port for custom HTTP handlers (e.g. serving `swagger.json`),
+gRPC-Gateway, and a gRPC server, see [this code example by CoreOS](https://github.com/philips/grpc-gateway-example/blob/master/cmd/serve.go) (and it's accompanying
+[blog post](https://coreos.com/blog/grpc-protobufs-swagger.html)).
diff --git a/docs/docs/mapping/grpc_api_configuration.md b/docs/docs/mapping/grpc_api_configuration.md
new file mode 100644
index 00000000000..6d69bbcc60f
--- /dev/null
+++ b/docs/docs/mapping/grpc_api_configuration.md
@@ -0,0 +1,142 @@
+---
+layout: default
+title: gRPC API Configuration
+nav_order: 3
+parent: Mapping
+---
+
+# gRPC API Configuration
+
+In some situations annotating the proto file of service is not an option. For example, you might not have control over the proto file, or you might want to expose the same gRPC API multiple times in completely different ways.
+
+gRPC-Gateway supports 2 ways of dealing with these situations:
+
+- [gRPC API Configuration](#grpc-api-configuration)
+ - [`generate_unbound_methods`](#generate_unbound_methods)
+ - [Using an external configuration file](#using-an-external-configuration-file)
+ - [Usage of gRPC API Configuration YAML files](#usage-of-grpc-api-configuration-yaml-files)
+
+## `generate_unbound_methods`
+
+Providing this parameter to the `protoc` plugin will make it produce the HTTP mapping even for methods without any `HttpRule` annotation. This is similar to how [Cloud Endpoints behaves](https://cloud.google.com/endpoints/docs/grpc/transcoding#where_to_configure_transcoding) and uses the way [gRPC itself](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) maps to HTTP/2:
+
+- HTTP method is `POST`
+- URI path is built from the service's name and method: `//` (e.g.: `/my.package.EchoService/Echo`)
+- HTTP body is the serialized protobuf message.
+
+NOTE: the same option is also supported by the `gen-openapiv2` plugin.
+
+## Using an external configuration file
+
+Google Cloud Platform offers a way to do this for services
+hosted with them called ["gRPC API Configuration"](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config). It can be used to define the behavior of a gRPC API service without modifications to the service itself in the form of [YAML](https://en.wikipedia.org/wiki/YAML) configuration files.
+
+gRPC-Gateway generators implement the [HTTP rules part](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#httprule) of this specification. This allows you to take a completely unannotated service proto file, add a YAML file describing its HTTP endpoints and use them together like an annotated proto file with the gRPC-Gateway generators.
+
+OpenAPI options may also be configured via ["OpenAPI Configuration"](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/internal/descriptor/openapiconfig/openapiconfig.proto) in the form of YAML configuration files.
+
+### Usage of gRPC API Configuration YAML files
+
+The following is equivalent to the basic [`README.md`](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/README.md#usage) example but without direct
+annotation for gRPC-Gateway in the proto file. Only some steps require minor changes to use a gRPC API Configuration YAML file instead:
+
+1. Define your service in gRPC as usual
+
+ your_service.proto:
+
+ ```protobuf
+ syntax = "proto3";
+ package your.service.v1;
+ option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
+ message StringMessage {
+ string value = 1;
+ }
+
+ service YourService {
+ rpc Echo(StringMessage) returns (StringMessage) {}
+ }
+ ```
+
+2. Instead of annotating the proto file in this step leave it untouched
+ and create a `your_service.yaml` with the following content:
+
+ ```yaml
+ type: google.api.Service
+ config_version: 3
+
+ http:
+ rules:
+ - selector: your.service.v1.YourService.Echo
+ post: /v1/example/echo
+ body: "*"
+ ```
+
+ Use a [linter](http://www.yamllint.com/) to validate your YAML.
+
+3. Generate gRPC stub as before
+
+ ```sh
+ protoc -I . \
+ --go_out ./gen/go/ \
+ --go_opt paths=source_relative \
+ --go-grpc_out ./gen/go/ \
+ --go-grpc_opt paths=source_relative \
+ your/service/v1/your_service.proto
+ ```
+
+It will generate a stub file with path `./gen/go/your/service/v1/your_service.pb.go`.
+
+4. Implement your service in gRPC as usual
+
+5. Generate the reverse-proxy. Here we have to pass the path to
+ the `your_service.yaml` in addition to the proto file:
+
+ ```sh
+ protoc -I . \
+ --grpc-gateway_out ./gen/go \
+ --grpc-gateway_opt logtostderr=true \
+ --grpc-gateway_opt paths=source_relative \
+ --grpc-gateway_opt grpc_api_configuration=path/to/your_service.yaml \
+ your/service/v1/your_service.proto
+ ```
+
+ This will generate a reverse proxy `gen/go/your/service/v1/your_service.pb.gw.go` that is identical to the one produced for the annotated proto.
+
+ In situations where you only need the reverse-proxy you can use the `standalone=true` option when generating the code. This will ensure the `types` used within `your_service.pb.gw.go` reference the external source appropriately.
+
+ ```
+ protoc -I . \
+ --grpc-gateway_out ./gen/go \
+ --grpc-gateway_opt logtostderr=true \
+ --grpc-gateway_opt paths=source_relative \
+ --grpc-gateway_opt standalone=true \
+ --grpc-gateway_opt grpc_api_configuration=path/to/your_service.yaml \
+ your/service/v1/your_service.proto
+ ```
+
+6. Generate the optional your_service.swagger.json
+
+ ```sh
+ protoc -I . --openapiv2_out ./gen/go \
+ --openapiv2_opt grpc_api_configuration=path/to/your_service.yaml \
+ your/service/v1/your_service.proto
+ ```
+
+ or using an OpenAPI configuration file
+
+ ```sh
+ protoc -I . --openapiv2_out ./gen/go \
+ --openapiv2_opt grpc_api_configuration=path/to/your_service.yaml \
+ --openapiv2_opt openapi_configuration=path/to/your_service_swagger.yaml \
+ your/service/v1/your_service.proto
+ ```
+
+ For an example of an OpenAPI configuration file, see [unannotated_echo_service.swagger.yaml](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.swagger.yaml), which adds OpenAPI options to [unannotated_echo_service.proto](https://github.com/grpc-ecosystem/grpc-gateway/tree/master/examples/internal/proto/examplepb/unannotated_echo_service.proto).
+
+ ```sh
+ protoc -I . --openapiv2_out ./gen/go \
+ --openapiv2_opt grpc_api_configuration=path/to/your_service.yaml \
+ your/service/v1/your_service.proto
+ ```
+
+All other steps work as before. If you want you can remove the `googleapis` include path in step 3 and 4 as the unannotated proto no longer requires them.
diff --git a/docs/docs/mapping/httpbody_messages.md b/docs/docs/mapping/httpbody_messages.md
new file mode 100644
index 00000000000..4a3623b69bc
--- /dev/null
+++ b/docs/docs/mapping/httpbody_messages.md
@@ -0,0 +1,67 @@
+---
+layout: default
+title: HttpBody Messages
+nav_order: 1
+parent: Mapping
+---
+
+# HttpBody Messages
+
+The [HTTPBody](https://github.com/googleapis/googleapis/blob/master/google/api/httpbody.proto) messages allow a response message to be specified with custom data content and a custom content-type header. The values included in the HTTPBody response will be used verbatim in the returned message from the gateway. Make sure you format your response carefully!
+
+## Example Usage
+
+1. Define your service in gRPC with an httpbody response message
+
+```protobuf
+import "google/api/httpbody.proto";
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+
+service HttpBodyExampleService {
+ rpc HelloWorld(google.protobuf.Empty) returns (google.api.HttpBody) {
+ option (google.api.http) = {
+ get: "/helloworld"
+ };
+ }
+ rpc Download(google.protobuf.Empty) returns (stream google.api.HttpBody) {
+ option (google.api.http) = {
+ get: "/download"
+ };
+ }
+}
+```
+
+3. Generate gRPC and reverse-proxy stubs and implement your service.
+
+## Example service implementation
+
+```go
+func (*HttpBodyExampleService) Helloworld(ctx context.Context, in *empty.Empty) (*httpbody.HttpBody, error) {
+ return &httpbody.HttpBody{
+ ContentType: "text/html",
+ Data: []byte("Hello World"),
+ }, nil
+}
+
+func (HttpBodyExampleService) Download(_ *empty.Empty, stream HttpBodyExampleService_DownloadServer) error {
+ msgs := []*httpbody.HttpBody{
+ {
+ ContentType: "text/html",
+ Data: []byte("Hello 1"),
+ },
+ {
+ ContentType: "text/html",
+ Data: []byte("Hello 2"),
+ },
+ }
+
+ for _, msg := range msgs {
+ if err := stream.Send(msg); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+```
diff --git a/docs/docs/mapping/index.md b/docs/docs/mapping/index.md
new file mode 100644
index 00000000000..88e1a943f5d
--- /dev/null
+++ b/docs/docs/mapping/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Mapping
+nav_order: 2
+has_children: true
+---
diff --git a/docs/docs/mapping/patch_feature.md b/docs/docs/mapping/patch_feature.md
new file mode 100644
index 00000000000..61cb8d24380
--- /dev/null
+++ b/docs/docs/mapping/patch_feature.md
@@ -0,0 +1,83 @@
+---
+layout: default
+title: Patch feature
+nav_order: 2
+parent: Mapping
+---
+
+# Patch feature
+
+The HTTP PATCH method allows a resource to be partially updated.
+
+If a binding is mapped to patch and the request message has exactly one FieldMask message in it, additional code is rendered for the gateway handler that will populate the FieldMask based on the request body. FieldMask is treated as a regular field by the gateway if the request method is not PATCH, or if the HttpRule body is `"*"`
+
+There are two scenarios:
+
+- The FieldMask is hidden from the REST request as per the
+ [Google API design guide](https://cloud.google.com/apis/design/standard_methods#update) (as in the first additional binding in the
+ [UpdateV2](https://github.com/grpc-ecosystem/grpc-gateway/blob/370d869f65d1ffb3d07187fb0db238eca2371ce3/examples/internal/proto/examplepb/a_bit_of_everything.proto#L428-L431) example). In this case, the FieldMask is updated from the request body and set in the gRPC request message.
+- The FieldMask is exposed to the REST request (as in the second additional binding in the [UpdateV2](https://github.com/grpc-ecosystem/grpc-gateway/blob/370d869f65d1ffb3d07187fb0db238eca2371ce3/examples/internal/proto/examplepb/a_bit_of_everything.proto#L432-L435) example). For this case, the field mask is left untouched by the gateway.
+
+## Example Usage
+
+1. Create a PATCH request.
+
+ The PATCH request needs to include the message and the update mask.
+
+ ```protobuf
+ // UpdateV2Request request for update includes the message and the update mask
+ message UpdateV2Request {
+ ABitOfEverything abe = 1;
+ google.protobuf.FieldMask update_mask = 2;
+ }
+ ```
+
+2. Define your service in gRPC
+
+ If you want to use PATCH with fieldmask hidden from REST request only include the request message in the body.
+
+ ```protobuf
+ rpc UpdateV2(UpdateV2Request) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ put: "/v2/example/a_bit_of_everything/{abe.uuid}"
+ body: "abe"
+ additional_bindings {
+ patch: "/v2/example/a_bit_of_everything/{abe.uuid}"
+ body: "abe"
+ }
+ };
+ }
+ ```
+
+ If you want to use PATCH with fieldmask exposed to the REST request then include the entire request message.
+
+ ```protobuf
+ rpc UpdateV2(UpdateV2Request) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ patch: "/v2a/example/a_bit_of_everything/{abe.uuid}"
+ body: "*"
+ };
+ }
+ ```
+
+3. Generate gRPC and reverse-proxy stubs and implement your service.
+
+## cURL examples
+
+In the example below, we will partially update our ABitOfEverything resource by passing only the field we want to change. Since we are using the endpoint with field mask hidden we only need to pass the field we want to change ("string_value") and it will keep everything else in our resource the same.
+
+```sh
+$ curl \
+ --data '{"stringValue": "strprefix/foo"}' \
+ -X PATCH \
+ http://address:port/v2/example/a_bit_of_everything/1
+```
+
+If we know what fields we want to update then we can use PATCH with field mask approach. For this, we need to pass the resource and the update_mask. Below only the "single_nested" will get updated because that is what we specify in the field_mask.
+
+```sh
+$ curl \
+ --data '{"abe":{"singleNested":{"amount":457},"stringValue":"some value that will not get updated because not in the field mask"},"updateMask":"singleNested"}}' \
+ -X PATCH \
+ http://address:port/v2a/example/a_bit_of_everything/1
+```
diff --git a/docs/docs/operations/annotated_context.md b/docs/docs/operations/annotated_context.md
new file mode 100644
index 00000000000..1eaaddac0b6
--- /dev/null
+++ b/docs/docs/operations/annotated_context.md
@@ -0,0 +1,52 @@
+---
+layout: default
+title: Extracting the HTTP path pattern for a request
+nav_order: 4
+parent: Operations
+---
+
+# Extracting the HTTP path pattern for a request
+
+It is often interesting to know what [HTTP path pattern](https://github.com/googleapis/googleapis/blob/869d32e2f0af2748ab530646053b23a2b80d9ca5/google/api/http.proto#L61-L87) was matched for a specific request, for example for metrics. This article explains how to extract the HTTP path pattern from the request context.
+
+## Get HTTP Path pattern
+1. Define the HTTP path in the proto annotation. For example:
+
+```proto
+syntax = "proto3";
+option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/proto/examplepb";
+package grpc.gateway.examples.internal.proto.examplepb;
+
+import "google/api/annotations.proto";
+
+service LoginService {
+ rpc Login (LoginRequest) returns (LoginReply) {
+ option (google.api.http) = {
+ post: "/v1/example/login"
+ body: "*"
+ };
+ }
+}
+
+message LoginRequest {}
+
+message LoginReply {}
+```
+
+2. At runtime, get the HTTP path pattern from the annotated context, for example using the `WithMetadata` function.
+You can pass data to your backend by adding them to the gRPC metadata or push them to a metrics server.
+
+```go
+mux := runtime.NewServeMux(
+ runtime.WithMetadata(func(ctx context.Context, r *http.Request) metadata.MD {
+ md := make(map[string]string)
+ if method, ok := runtime.RPCMethod(ctx); ok {
+ md["method"] = method // /grpc.gateway.examples.internal.proto.examplepb.LoginService/Login
+ }
+ if pattern, ok := runtime.HTTPPathPattern(ctx); ok {
+ md["pattern"] = pattern // /v1/example/login
+ }
+ return metadata.New(md)
+ }),
+)
+```
\ No newline at end of file
diff --git a/docs/docs/operations/aws_gateway_integration.md b/docs/docs/operations/aws_gateway_integration.md
new file mode 100644
index 00000000000..0544512fdec
--- /dev/null
+++ b/docs/docs/operations/aws_gateway_integration.md
@@ -0,0 +1,19 @@
+---
+layout: default
+title: AWS gateway integration
+nav_order: 3
+parent: Operations
+---
+
+# AWS gateway integration
+
+## Import OpenAPI documentation into AWS API Gateway
+
+The AWS API Gateway service allows importing of an OpenAPI specification to create a REST API. The process is very straightforward and can be found [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html).
+
+Here are some tips to consider when importing the documentation:
+
+1. Remove any circular dependencies (these aren't supported by the parser).
+2. Remove security-related annotations (These annotations aren't well supported by the parser).
+3. Max length of fields are reviewed by the parser but the errors aren't self-explanatory. Review the [specification](https://swagger.io/specification/v2/) to verify that the requirements are met.
+4. API gateway errors aren't great, but you can use this [page](https://apidevtools.org/swagger-parser/online/) for structure validation.
diff --git a/docs/docs/operations/health_check.md b/docs/docs/operations/health_check.md
new file mode 100644
index 00000000000..b8a8be5a3ee
--- /dev/null
+++ b/docs/docs/operations/health_check.md
@@ -0,0 +1,60 @@
+---
+layout: default
+title: Health check
+nav_order: 1
+parent: Operations
+---
+
+# Health check
+
+## With the [gRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md)
+
+To use the gRPC health checking protocol you must add the two health checking methods, `Watch` and `Check`.
+
+## Registering the health server
+
+1. Add `google.golang.org/grpc/health/grpc_health_v1` to your imports
+2. Register the health server with `grpc_health_v1.RegisterHealthServer(grpcServer, yourService)`
+
+## Adding the health check methods
+
+1. Check method
+
+```go
+func (s *serviceServer) Check(ctx context.Context, in *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
+ return &health.HealthCheckResponse{Status: health.HealthCheckResponse_SERVING}, nil
+}
+```
+
+2. Watch method
+
+```go
+func (s *serviceServer) Watch(in *health.HealthCheckRequest, _ health.Health_WatchServer) error {
+ // Example of how to register both methods but only implement the Check method.
+ return status.Error(codes.Unimplemented, "unimplemented")
+}
+```
+
+3. You can test the functionality with [GRPC health probe](https://github.com/grpc-ecosystem/grpc-health-probe).
+
+## Adding `/healthz` endpoint to runtime.ServeMux
+
+To automatically register a `/healthz` endpoint in your `ServeMux` you can use
+the `ServeMuxOption` `WithHealthzEndpoint`
+which takes in a connection to your registered gRPC server.
+
+This endpoint will forward a request to the `Check` method described above to really check the health of the
+whole system, not only the gateway itself. If your server doesn't implement the health checking protocol each request
+to `/healthz` will result in the following:
+
+```json
+{"code":12,"message":"unknown service grpc.health.v1.Health","details":[]}
+```
+
+If you've implemented multiple services in your server you can target specific services with the `?service=`
+query parameter. This will then be added to the `health.HealthCheckRequest` in the `Service` property. With that you can
+write your own logic to handle that in the health checking methods.
+
+Analogously, to register an `{/endpoint/path}` endpoint in your `ServeMux` with a user-defined endpoint path, you can use
+the `ServeMuxOption` `WithHealthEndpointAt`, which accepts a connection to your registered gRPC server
+together with a custom `endpointPath string` parameter.
diff --git a/docs/docs/operations/index.md b/docs/docs/operations/index.md
new file mode 100644
index 00000000000..9ec5ab4b6fe
--- /dev/null
+++ b/docs/docs/operations/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Operations
+nav_order: 3
+has_children: true
+---
diff --git a/docs/docs/operations/inject_router.md b/docs/docs/operations/inject_router.md
new file mode 100644
index 00000000000..d3969b653d9
--- /dev/null
+++ b/docs/docs/operations/inject_router.md
@@ -0,0 +1,54 @@
+---
+layout: default
+title: Adding custom routes to the mux
+nav_order: 0
+parent: Operations
+---
+
+# Adding custom routes to the mux
+
+The gRPC-Gateway allows you to add custom routes to the serve mux, for example, if you want to support a use case that isn't supported by the gRPC-Gateway, like file uploads.
+
+## Example
+
+```go
+package main
+
+import (
+ "context"
+ "net/http"
+
+ pb "github.com/grpc-ecosystem/grpc-gateway/v2/examples/internal/helloworld"
+ "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+)
+
+func main() {
+ ctx := context.TODO()
+ mux := runtime.NewServeMux()
+ // Register generated routes to mux
+ err := pb.RegisterGreeterHandlerServer(ctx, mux, &GreeterServer{})
+ if err != nil {
+ panic(err)
+ }
+ // Register custom route for GET /hello/{name}
+ err = mux.HandlePath("GET", "/hello/{name}", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
+ w.Write([]byte("hello " + pathParams["name"]))
+ })
+ if err != nil {
+ panic(err)
+ }
+ http.ListenAndServe(":8080", mux)
+}
+
+// GreeterServer is the server API for Greeter service.
+type GreeterServer struct {
+
+}
+
+// SayHello implement to say hello
+func (h *GreeterServer) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
+ return &pb.HelloReply{
+ Message: "hello " + req.Name,
+ }, nil
+}
+```
diff --git a/docs/docs/operations/tracing.md b/docs/docs/operations/tracing.md
new file mode 100644
index 00000000000..219d6a859cf
--- /dev/null
+++ b/docs/docs/operations/tracing.md
@@ -0,0 +1,182 @@
+---
+layout: default
+title: Tracing
+nav_order: 2
+parent: Operations
+---
+
+# Tracing
+
+## With [OpenCensus.io](https://opencensus.io/) and [AWS X-ray](https://aws.amazon.com/xray/)
+
+### Adding tracing using AWS-Xray as the exporter
+
+This example uses the AWS-Xray exporter with a global trace setting. Note that AWS X-ray exporter does not handle any metrics only tracing.
+
+1. Add the following imports
+
+```go
+xray "contrib.go.opencensus.io/exporter/aws"
+"go.opencensus.io/plugin/ocgrpc"
+"go.opencensus.io/plugin/ochttp"
+"go.opencensus.io/trace"
+```
+
+2. Register the AWS X-ray exporter for the GRPC server
+
+```go
+xrayExporter, err := xray.NewExporter(
+ xray.WithVersion("latest"),
+ // Add your AWS region.
+ xray.WithRegion("ap-southeast-1"),
+)
+if err != nil {
+ // Handle any error.
+}
+// Do not forget to call Flush() before the application terminates.
+defer xrayExporter.Flush()
+
+// Register the trace exporter.
+trace.RegisterExporter(xrayExporter)
+```
+
+3. Add a global tracing configuration
+
+```go
+// Always trace in this example.
+// In production this can be set to a trace.ProbabilitySampler.
+trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
+```
+
+4. Add `ocgrpc.ClientHandler` for tracing the gRPC client calls
+
+```go
+// Example using DialContext
+conn, err := grpc.DialContext(
+ // Other options goes here.
+ // Add ocgrpc.ClientHandler for tracing the grpc client calls.
+ grpc.WithStatsHandler(&ocgrpc.ClientHandler{}),
+)
+```
+
+5. Wrap the gateway mux with the OpenCensus HTTP handler
+
+```go
+gwmux := runtime.NewServeMux()
+
+openCensusHandler := &ochttp.Handler{
+ Handler: gwmux,
+}
+
+gwServer := &http.Server{
+ Addr: "0.0.0.0:10000",
+ Handler: openCensusHandler,
+ }),
+}
+```
+
+### Without a global configuration
+
+In this example we have added the [gRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) and we do not wish to trace any health checks.
+
+1. Follow step `1`, `2` and `4` from the previous section.
+
+2. Since we are not using a global configuration we can decide what paths we want to trace.
+
+```go
+gwmux := runtime.NewServeMux()
+
+openCensusHandler := &ochttp.Handler{
+ Handler: gwmux,
+ GetStartOptions: func(r *http.Request) trace.StartOptions {
+ startOptions := trace.StartOptions{}
+ if strings.HasPrefix(r.URL.Path, "/api") {
+ // This example will always trace anything starting with /api.
+ startOptions.Sampler = trace.AlwaysSample()
+ }
+ return startOptions
+ },
+}
+```
+
+4. No global configuration means we have to use the [per span sampler](https://opencensus.io/tracing/sampling/#per-span-sampler).
+
+#### A method we want to trace
+
+```go
+func (s *service) Name(ctx context.Context, req *pb.Request) (*pb.Response, error) {
+ // Here we add the span ourselves.
+ ctx, span := trace.StartSpan(ctx, "name.to.use.in.trace", trace.
+ // Select a sampler that fits your implementation.
+ WithSampler(trace.AlwaysSample()))
+ defer span.End()
+ /// Other stuff goes here.
+}
+```
+
+#### A method we do not wish to trace
+
+```go
+func (s *service) Check(ctx context.Context, in *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
+ // Note no span here.
+ return &health.HealthCheckResponse{Status: health.HealthCheckResponse_SERVING}, nil
+}
+```
+
+## OpenTracing Support
+
+If your project uses [OpenTracing](https://github.com/opentracing/opentracing-go) and you'd like spans to propagate through the gateway, you can add some middleware which parses the incoming HTTP headers to create a new span correctly.
+
+```go
+import (
+ "github.com/opentracing/opentracing-go"
+ "github.com/opentracing/opentracing-go/ext"
+)
+
+var grpcGatewayTag = opentracing.Tag{Key: string(ext.Component), Value: "grpc-gateway"}
+
+func tracingWrapper(h http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ parentSpanContext, err := opentracing.GlobalTracer().Extract(
+ opentracing.HTTPHeaders,
+ opentracing.HTTPHeadersCarrier(r.Header))
+ if err == nil || err == opentracing.ErrSpanContextNotFound {
+ serverSpan := opentracing.GlobalTracer().StartSpan(
+ "ServeHTTP",
+ // this is magical, it attaches the new span to the parent parentSpanContext, and creates an unparented one if empty.
+ ext.RPCServerOption(parentSpanContext),
+ grpcGatewayTag,
+ )
+ r = r.WithContext(opentracing.ContextWithSpan(r.Context(), serverSpan))
+ defer serverSpan.Finish()
+ }
+ h.ServeHTTP(w, r)
+ })
+}
+
+// Then just wrap the mux returned by runtime.NewServeMux() like this
+if err := http.ListenAndServe(":8080", tracingWrapper(mux)); err != nil {
+ log.Fatalf("failed to start gateway server on 8080: %v", err)
+}
+```
+
+Finally, don't forget to add a tracing interceptor when registering
+the services. E.g.
+
+```go
+import (
+ "google.golang.org/grpc"
+ "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
+)
+
+opts := []grpc.DialOption{
+ grpc.WithUnaryInterceptor(
+ grpc_opentracing.UnaryClientInterceptor(
+ grpc_opentracing.WithTracer(opentracing.GlobalTracer()),
+ ),
+ ),
+}
+if err := pb.RegisterMyServiceHandlerFromEndpoint(ctx, mux, serviceEndpoint, opts); err != nil {
+ log.Fatalf("could not register HTTP service: %v", err)
+}
+```
diff --git a/docs/docs/overview/background.md b/docs/docs/overview/background.md
new file mode 100644
index 00000000000..9e0fbc84c65
--- /dev/null
+++ b/docs/docs/overview/background.md
@@ -0,0 +1,12 @@
+---
+layout: default
+title: Background
+nav_order: 0
+parent: Overview
+---
+
+# Background
+
+gRPC is great -- it generates API clients and server stubs in many programming languages, it is fast, easy-to-use, bandwidth-efficient and its design is combat-proven by Google. However, you might still want to provide a traditional RESTful API as well. Reasons can range from maintaining backwards-compatibility, supporting languages or clients not well supported by gRPC to simply maintaining the aesthetics and tooling involved with a RESTful architecture.
+
+This project aims to provide that HTTP+JSON interface to your gRPC service. A small amount of configuration in your service to attach HTTP semantics is all that's needed to generate a reverse-proxy with this library.
diff --git a/docs/docs/overview/index.md b/docs/docs/overview/index.md
new file mode 100644
index 00000000000..481fbe842c2
--- /dev/null
+++ b/docs/docs/overview/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Overview
+nav_order: 1
+has_children: true
+---
diff --git a/docs/docs/overview/usage.md b/docs/docs/overview/usage.md
new file mode 100644
index 00000000000..d9e7b0545d5
--- /dev/null
+++ b/docs/docs/overview/usage.md
@@ -0,0 +1,10 @@
+---
+layout: default
+title: How do I use this?
+nav_order: 1
+parent: Overview
+---
+
+# How do I use this?
+
+Follow the [instructions](https://github.com/grpc-ecosystem/grpc-gateway#usage) in the [README](https://github.com/grpc-ecosystem/grpc-gateway#readme).
diff --git a/docs/docs/related_projects.md b/docs/docs/related_projects.md
new file mode 100644
index 00000000000..e9600bb9bd9
--- /dev/null
+++ b/docs/docs/related_projects.md
@@ -0,0 +1,23 @@
+---
+layout: default
+title: Related projects
+nav_order: 8
+---
+
+# Related projects
+
+- [grpc-dynamic-gateway](https://github.com/konsumer/grpc-dynamic-gateway)
+
+ A dynamically configured alternative to the grpc-gateway written in Node.
+
+- [rest2grpc](https://www.npmjs.com/package/rest2grpc)
+
+ A statically configured alternative to the grpc-gateway written in Node.
+
+- The Envoy proxy [gRPC-JSON transcoder](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter)
+
+ An Envoy proxy filter that translates incoming JSON requests to gRPC and back.
+
+- Google Cloud Platform [HTTP/JSON gRPC transcoding](https://cloud.google.com/endpoints/docs/grpc/transcoding)
+
+ A GCP product that behaves like the grpc-gateway.
diff --git a/docs/docs/tutorials/adding_annotations.md b/docs/docs/tutorials/adding_annotations.md
new file mode 100644
index 00000000000..bf0b13d7a23
--- /dev/null
+++ b/docs/docs/tutorials/adding_annotations.md
@@ -0,0 +1,215 @@
+---
+layout: default
+title: Adding gRPC-Gateway annotations to an existing proto file
+nav_order: 4
+parent: Tutorials
+---
+
+# Adding gRPC-Gateway annotations to an existing proto file
+
+Now that we've got a working Go gRPC server, we need to add the gRPC-Gateway annotations.
+
+The annotations define how gRPC services map to the JSON request and response. When using protocol buffers, each RPC must define the HTTP method and path using the `google.api.http` annotation.
+
+So we will need to add the `google/api/http.proto` import to the proto file. We also need to add the HTTP->gRPC mapping we want. In this case, we're mapping `POST /v1/example/echo` to our `SayHello` RPC.
+
+```protobuf
+syntax = "proto3";
+
+package helloworld;
+
+import "google/api/annotations.proto";
+
+// Here is the overall greeting service definition where we define all our endpoints
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {
+ option (google.api.http) = {
+ post: "/v1/example/echo"
+ body: "*"
+ };
+ }
+}
+
+// The request message containing the user's name
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
+```
+
+See [a_bit_of_everything.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto) for examples of more annotations you can add to customize gateway behavior.
+
+## Generating the gRPC-Gateway stubs
+
+Now that we've got the gRPC-Gateway annotations added to the proto file, we need to use the gRPC-Gateway generator to generate the stubs.
+
+### Using buf
+
+We'll need to add the gRPC-Gateway generator to the generation configuration:
+
+```yaml
+version: v1
+plugins:
+ - name: go
+ out: proto
+ opt: paths=source_relative
+ - name: go-grpc
+ out: proto
+ opt: paths=source_relative,require_unimplemented_servers=false
+ - name: grpc-gateway
+ out: proto
+ opt: paths=source_relative
+```
+
+We'll also need to add the `googleapis` dependency to our `buf.yaml` file:
+
+```yaml
+version: v1
+name: buf.build/myuser/myrepo
+deps:
+ - buf.build/googleapis/googleapis
+```
+
+Then we need to run `buf mod update` to select a version of the dependency to use.
+
+And that's it! Now if you run:
+
+```sh
+$ buf generate
+```
+
+It should produce a `*.gw.pb.go` file.
+
+### Using `protoc`
+
+Before we can generate the stubs with `protoc`, we need to copy some dependencies into our proto file structure. Copy a subset of the `googleapis`
+from the [official repository](https://github.com/googleapis/googleapis) to your local proto file structure. It should look like this afterwards:
+
+```
+proto
+βββ google
+β βββ api
+β βββ annotations.proto
+β βββ http.proto
+βββ helloworld
+ βββ hello_world.proto
+```
+
+Now we need to add the gRPC-Gateway generator to the `protoc` invocation:
+
+```sh
+$ protoc -I ./proto \
+ --go_out ./proto --go_opt paths=source_relative \
+ --go-grpc_out ./proto --go-grpc_opt paths=source_relative \
+ --grpc-gateway_out ./proto --grpc-gateway_opt paths=source_relative \
+ ./proto/helloworld/hello_world.proto
+```
+
+This should generate a `*.gw.pb.go` file.
+
+We also need to add and serve the gRPC-Gateway mux in our `main.go` file.
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+ "net"
+ "net/http"
+
+ "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials/insecure"
+
+ helloworldpb "github.com/myuser/myrepo/proto/helloworld"
+)
+
+type server struct{
+ helloworldpb.UnimplementedGreeterServer
+}
+
+func NewServer() *server {
+ return &server{}
+}
+
+func (s *server) SayHello(ctx context.Context, in *helloworldpb.HelloRequest) (*helloworldpb.HelloReply, error) {
+ return &helloworldpb.HelloReply{Message: in.Name + " world"}, nil
+}
+
+func main() {
+ // Create a listener on TCP port
+ lis, err := net.Listen("tcp", ":8080")
+ if err != nil {
+ log.Fatalln("Failed to listen:", err)
+ }
+
+ // Create a gRPC server object
+ s := grpc.NewServer()
+ // Attach the Greeter service to the server
+ helloworldpb.RegisterGreeterServer(s, &server{})
+ // Serve gRPC server
+ log.Println("Serving gRPC on 0.0.0.0:8080")
+ go func() {
+ log.Fatalln(s.Serve(lis))
+ }()
+
+ // Create a client connection to the gRPC server we just started
+ // This is where the gRPC-Gateway proxies the requests
+ conn, err := grpc.DialContext(
+ context.Background(),
+ "0.0.0.0:8080",
+ grpc.WithBlock(),
+ grpc.WithTransportCredentials(insecure.NewCredentials()),
+ )
+ if err != nil {
+ log.Fatalln("Failed to dial server:", err)
+ }
+
+ gwmux := runtime.NewServeMux()
+ // Register Greeter
+ err = helloworldpb.RegisterGreeterHandler(context.Background(), gwmux, conn)
+ if err != nil {
+ log.Fatalln("Failed to register gateway:", err)
+ }
+
+ gwServer := &http.Server{
+ Addr: ":8090",
+ Handler: gwmux,
+ }
+
+ log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090")
+ log.Fatalln(gwServer.ListenAndServe())
+}
+```
+
+For more examples, please refer to [our boilerplate repository](https://github.com/johanbrandhorst/grpc-gateway-boilerplate).
+
+## Testing the gRPC-Gateway
+
+Now we can start the server:
+
+```sh
+$ go run main.go
+```
+
+Then we use cURL to send HTTP requests:
+
+```sh
+$ curl -X POST -k http://localhost:8090/v1/example/echo -d '{"name": " hello"}'
+```
+
+```
+{"message":"hello world"}
+```
+
+Hopefully, that gives a bit of understanding of how to use the gRPC-Gateway.
+
+Full source code of hello world program can be found here [helloworld-grpc-gateway](https://github.com/iamrajiv/helloworld-grpc-gateway).
+
+[Next](learn_more.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/docs/tutorials/creating_main.go.md b/docs/docs/tutorials/creating_main.go.md
new file mode 100644
index 00000000000..de1f0ae7aca
--- /dev/null
+++ b/docs/docs/tutorials/creating_main.go.md
@@ -0,0 +1,58 @@
+---
+layout: default
+title: Creating main.go
+nav_order: 3
+parent: Tutorials
+---
+
+# Creating main.go
+
+Before creating `main.go` file we are assuming that the user has created a `go.mod` with the name `github.com/myuser/myrepo`, if not please refer to [Creating go.mod file](introduction.md#creating-gomod-file). The import here is using the path to the generated files in `proto/helloworld` relative to the root of the repository.
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+ "net"
+
+ "google.golang.org/grpc"
+
+ helloworldpb "github.com/myuser/myrepo/proto/helloworld"
+)
+
+type server struct{
+ helloworldpb.UnimplementedGreeterServer
+}
+
+func NewServer() *server {
+ return &server{}
+}
+
+func (s *server) SayHello(ctx context.Context, in *helloworldpb.HelloRequest) (*helloworldpb.HelloReply, error) {
+ return &helloworldpb.HelloReply{Message: in.Name + " world"}, nil
+}
+
+func main() {
+ // Create a listener on TCP port
+ lis, err := net.Listen("tcp", ":8080")
+ if err != nil {
+ log.Fatalln("Failed to listen:", err)
+ }
+
+ // Create a gRPC server object
+ s := grpc.NewServer()
+ // Attach the Greeter service to the server
+ helloworldpb.RegisterGreeterServer(s, &server{})
+ // Serve gRPC Server
+ log.Println("Serving gRPC on 0.0.0.0:8080")
+ log.Fatal(s.Serve(lis))
+}
+```
+
+## Read More
+
+For more refer to gRPC docs [https://grpc.io/docs/languages/go/](https://grpc.io/docs/languages/go/).
+
+[Next](adding_annotations.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/docs/tutorials/generating_stubs/index.md b/docs/docs/tutorials/generating_stubs/index.md
new file mode 100644
index 00000000000..ec873a6a5d3
--- /dev/null
+++ b/docs/docs/tutorials/generating_stubs/index.md
@@ -0,0 +1,9 @@
+---
+layout: default
+title: Generating stubs
+parent: Tutorials
+nav_order: 2
+has_children: true
+---
+
+For generating the stubs, we have two alternatives: `protoc` and `buf`. `protoc` is the more classic generation experience that is used widely in the industry, but it has a pretty steep learning curve. `buf` is a newer tool that is built with user experience and speed in mind. It also offers linting and breaking change detection, something `protoc` doesn't offer. We offer instructions for both here.
diff --git a/docs/docs/tutorials/generating_stubs/using_buf.md b/docs/docs/tutorials/generating_stubs/using_buf.md
new file mode 100644
index 00000000000..f7d657fb4b9
--- /dev/null
+++ b/docs/docs/tutorials/generating_stubs/using_buf.md
@@ -0,0 +1,45 @@
+---
+layout: default
+title: Generating stubs using buf
+nav_order: 0
+parent: Generating stubs
+grand_parent: Tutorials
+---
+
+# Generating stubs using buf
+
+[Buf](https://github.com/bufbuild/buf) is a tool that provides various protobuf utilities such as linting, breaking change detection and generation. Please find installation instructions on [https://docs.buf.build/installation/](https://docs.buf.build/installation/).
+
+It is configured through a `buf.yaml` file that should be checked in to the root of your Protobuf file hierarchy. Buf will automatically read this file if present. Configuration can also be provided via the command-line flag `--config`, which accepts a path to a `.json` or `.yaml` file, or direct JSON or YAML data. As opposed to `protoc`, where all `.proto` files are manually specified on the command-line, buf operates by recursively discovering all `.proto` files under configuration and building them.
+
+The following is an example of a valid configuration, and you would put it in the root of your Protobuf file hierarchy, e.g. in `proto/buf.yaml` relative to the root of your repository.
+
+```yaml
+version: v1
+name: buf.build/myuser/myrepo
+```
+
+To generate type and gRPC stubs for Go, create the file `buf.gen.yaml`:
+
+```yaml
+version: v1
+plugins:
+ - name: go
+ out: proto
+ opt: paths=source_relative
+ - name: go-grpc
+ out: proto
+ opt: paths=source_relative
+```
+
+We use the `go` and `go-grpc` plugins to generate Go types and gRPC service definitions. We're outputting the generated files relative to the `proto` folder, and we're using the `paths=source_relative` option, which means that the generated files will appear in the same directory as the source `.proto` file.
+
+Then run
+
+```sh
+$ buf generate
+```
+
+This will have generated a `*.pb.go` and a `*_grpc.pb.go` file for each protobuf package in our `proto` file hierarchy.
+
+[Next](../creating_main.go.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/docs/tutorials/generating_stubs/using_protoc.md b/docs/docs/tutorials/generating_stubs/using_protoc.md
new file mode 100644
index 00000000000..b72eeb1120d
--- /dev/null
+++ b/docs/docs/tutorials/generating_stubs/using_protoc.md
@@ -0,0 +1,24 @@
+---
+layout: default
+title: Generating stubs using protoc
+nav_order: 1
+parent: Generating stubs
+grand_parent: Tutorials
+---
+
+# Generating stubs using protoc
+
+Here's an example of what a `protoc` command might look like to generate Go stubs, assuming that you're at the root of your repository and you have your proto files in a directory called `proto`:
+
+```sh
+$ protoc -I ./proto \
+ --go_out ./proto --go_opt paths=source_relative \
+ --go-grpc_out ./proto --go-grpc_opt paths=source_relative \
+ ./proto/helloworld/hello_world.proto
+```
+
+We use the `go` and `go-grpc` plugins to generate Go types and gRPC service definitions. We're outputting the generated files relative to the `proto` folder, and we're using the `paths=source_relative` option, which means that the generated files will appear in the same directory as the source `.proto` file.
+
+This will have generated a `*.pb.go` and a `*_grpc.pb.go` file for `proto/helloworld/hello_world.proto`.
+
+[Next](../creating_main.go.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/docs/tutorials/index.md b/docs/docs/tutorials/index.md
new file mode 100644
index 00000000000..ad3f51c5163
--- /dev/null
+++ b/docs/docs/tutorials/index.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Tutorials
+nav_order: 6
+has_children: true
+---
diff --git a/docs/docs/tutorials/introduction.md b/docs/docs/tutorials/introduction.md
new file mode 100644
index 00000000000..d179c94a22d
--- /dev/null
+++ b/docs/docs/tutorials/introduction.md
@@ -0,0 +1,55 @@
+---
+layout: default
+title: Introduction to the gRPC-Gateway
+nav_order: 0
+parent: Tutorials
+---
+
+# Introduction to the gRPC-Gateway
+
+We all know that gRPC is not a tool for everything. There are cases where we still want to provide a traditional HTTP/JSON API. The reasons can range from maintaining backward-compatibility to supporting programming languages or clients not well supported by gRPC. But writing another service just to expose an HTTP/JSON API is quite a time consuming and tedious task.
+
+So is there any way to code just once, but provide APIs in both gRPC and HTTP/JSON at the same time?
+
+The answer is Yes.
+
+The gRPC-Gateway is a plugin of the Google protocol buffers compiler [protoc](https://github.com/protocolbuffers/protobuf). It reads protobuf service definitions and generates a reverse-proxy server which translates a RESTful HTTP API into gRPC. This server is generated according to the [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46) annotations in your service definitions.
+
+This helps you provide your APIs in both gRPC and HTTP/JSON format at the same time.
+
+
+
+
+
+## Prerequisites
+
+Before we start coding, we have to install some tools.
+
+We will be using a Go gRPC server in the examples, so please install Go first from [https://golang.org/dl/](https://golang.org/dl/).
+
+After installing Go, use `go get` to download the following packages:
+
+```sh
+$ go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
+$ go get google.golang.org/protobuf/cmd/protoc-gen-go
+$ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
+```
+
+This installs the `protoc` generator plugins we need to generate the stubs. Make sure to add `$GOPATH/bin` to your `$PATH` so that executables installed via `go get` are available on your `$PATH`.
+
+We will be working in a new module for this tutorial, so go ahead and create that in a folder of your choosing now:
+
+### Creating go.mod file
+
+Start your module using the [go mod init command](https://golang.org/cmd/go/#hdr-Initialize_new_module_in_current_directory) to create a go.mod file.
+
+Run the `go mod init` command, giving it the path of the module your code will be in. Here, use github.com/myuser/myrepo for the module path -- in production code, this would be the URL from which your module can be downloaded.
+
+```sh
+$ go mod init github.com/myuser/myrepo
+go: creating new go.mod: module github.com/myuser/myrepo
+```
+
+The `go mod init` command creates a go.mod file that identifies your code as a module that might be used from other code. The file you just created includes only the name of your module and the Go version your code supports. But as you add dependencies -- meaning packages from other modules -- the go.mod file will list the specific module versions to use. This keeps builds reproducible and gives you direct control over which module versions to use.
+
+[Next](simple_hello_world.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/docs/tutorials/learn_more.md b/docs/docs/tutorials/learn_more.md
new file mode 100644
index 00000000000..b9d950da28e
--- /dev/null
+++ b/docs/docs/tutorials/learn_more.md
@@ -0,0 +1,20 @@
+---
+layout: default
+title: Learn More
+nav_order: 5
+parent: Tutorials
+---
+
+# Learn More
+
+## How it works
+
+When the HTTP request arrives at the gRPC-Gateway, it parses the JSON data into a protobuf message. It then makes a normal Go gRPC client request using the parsed protobuf message. The Go gRPC client encodes the protobuf structure into the protobuf binary format and sends it to the gRPC server. The gRPC Server handles the request and returns the response in the protobuf binary format. The Go gRPC client parses it into a protobuf message and returns it to the gRPC-Gateway, which encodes the protobuf message to JSON and returns it to the original client.
+
+## google.api.http
+
+Read more about `google.api.http` in [the source file documentation](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto).
+
+## HTTP and gRPC Transcoding
+
+Read more about HTTP and gRPC Transcoding on [AIP 127](https://google.aip.dev/127).
diff --git a/docs/docs/tutorials/simple_hello_world.md b/docs/docs/tutorials/simple_hello_world.md
new file mode 100644
index 00000000000..71251833251
--- /dev/null
+++ b/docs/docs/tutorials/simple_hello_world.md
@@ -0,0 +1,40 @@
+---
+layout: default
+title: Creating a simple hello world with gRPC
+nav_order: 1
+parent: Tutorials
+---
+
+# Creating a simple hello world with gRPC
+
+To understand the gRPC-Gateway we are going to first make a hello world gRPC service.
+
+## Defining your gRPC service using protocol buffers
+
+Before we create a gRPC service, we should create a proto file to define what we need, here we create a file named `hello_world.proto` in the directory `proto/helloworld/hello_world.proto`.
+
+The gRPC service is defined using [Google Protocol Buffers](https://developers.google.com/protocol-buffers). To learn more about how to define a service in a `.proto` file see their [Basics tutorial](https://grpc.io/docs/languages/go/basics/). For now, all you need to know is that both the server and the client stub have a `SayHello()` RPC method that takes a `HelloRequest` parameter from the client and returns a `HelloReply` from the server, and that the method is defined like this:
+
+```protobuf
+syntax = "proto3";
+
+package helloworld;
+
+// The greeting service definition
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
+```
+
+[Next](generating_stubs/index.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
diff --git a/docs/favicon.ico b/docs/favicon.ico
new file mode 100644
index 00000000000..d52f5093085
Binary files /dev/null and b/docs/favicon.ico differ
diff --git a/docs/index.md b/docs/index.md
index 47b6ec026fc..88910e1484a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,27 +1,53 @@
-# grpc-gateway
+---
+layout: default
+title: gRPC-Gateway
+nav_order: 0
+description: "Documentation site for the gRPC-Gateway"
+permalink: /
+---
-[](https://travis-ci.org/grpc-ecosystem/grpc-gateway)
+# gRPC-Gateway
+{: .fs-9 }
-grpc-gateway is a plugin of [protoc](http://github.com/google/protobuf).
-It reads [gRPC](http://github.com/grpc/grpc-common) service definition,
-and generates a reverse-proxy server which translates a RESTful JSON API into gRPC.
-This server is generated according to [custom options](https://cloud.google.com/service-management/reference/rpc/google.api#http) in your gRPC definition.
+gRPC-Gateway is a plugin of [protoc](https://github.com/protocolbuffers/protobuf). It reads a [gRPC](https://grpc.io/) service definition and generates a reverse-proxy server which translates a RESTful JSON API into gRPC. This server is generated according to [custom options](https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#http) in your gRPC definition.
+{: .fs-6 .fw-300 }
-It helps you to provide your APIs in both gRPC and RESTful style at the same time.
+[Get started](#getting-started){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } [View it on GitHub](https://github.com/grpc-ecosystem/grpc-gateway){: .btn .fs-5 .mb-4 .mb-md-0 }
-
+---
-To learn more about us check out our documentation on:
+## Getting started
-* [Our background](_docs/background.md)
-* [Installation and usage](_docs/usage.md)
-* [Examples](_docs/examples.md)
-* [Features](_docs/features.md)
+
+
+
+
+
+gRPC-Gateway helps you to provide your APIs in both gRPC and RESTful style at the same time.
-# Contribution
-See [CONTRIBUTING.md](http://github.com/grpc-ecosystem/grpc-gateway/blob/master/CONTRIBUTING.md).
+
+
+
+
+To learn more about gRPC-Gateway check out the documentation.
+
+## Contribution
+
+See [CONTRIBUTING.md](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/CONTRIBUTING.md).
+
+## License
+
+gRPC-Gateway is licensed under the BSD 3-Clause License.
-# License
-grpc-gateway is licensed under the BSD 3-Clause License.
See [LICENSE.txt](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt) for more details.
+
+### Thank you to the contributors of gRPC-Gateway
+
+
+{% for contributor in site.github.contributors %}
+