### Install and Run gRPC-Gateway Example Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/browser/README.md Installs necessary dependencies and runs the main build process for the gRPC-Gateway browser example. ```shell npm install -g gulp-cli npm install gulp ``` -------------------------------- ### Build and Run gRPC-Gateway Example Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/README.md Steps to install Node.js dependencies, build the project using gulp, and prepare the backend for the example. ```bash # Make sure you are in the correct directory: # $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/v2/examples $ cd examples/internal/browser $ pwd # Install gulp $ npm install -g gulp-cli $ npm install $ gulp # Run $ gulp bower $ gulp backends ``` -------------------------------- ### Serve gRPC-Gateway Example for Browser Testing Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/browser/README.md Starts a local development server to serve the gRPC-Gateway example, allowing integration testing directly in a web browser. ```shell gulp serve ``` -------------------------------- ### Initial Go Get Commands Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Attempt to download and install gRPC-Gateway and related packages using `go get`. This step may fail due to path issues in Cygwin. ```bash 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 ``` -------------------------------- ### Install Binaries via Go Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Install the required gRPC-Gateway and protocol buffer compiler plugins into your $GOBIN directory. ```sh 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 ``` ```sh go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv3 ``` -------------------------------- ### Configure per-request tracing options Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/tracing.md Customize tracing behavior for specific requests by implementing `GetStartOptions`. This example traces paths starting with '/api'. ```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 }, } ``` -------------------------------- ### Example gRPC-Gateway main.go program Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/faq.md This example demonstrates how to use a custom wrapper of runtime.ServeMux to add custom functionality as middleware. It leverages existing third-party libraries in Go. ```go package main import ( "context" "flag" "net/http" "os" "os/signal" "path/filepath" "syscall" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/protobuf/encoding/protojson" // The following import is generated by protoc-gen-grpc-gateway. // It is not needed if you are using the grpc-gateway directly. // You may need to change the import path to match your project structure. // For example, if your proto files are in "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb", // you would use: // "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb" "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb" ) var ( // commandLine activates the HTTP/JSON to Protobuf API // If empty, the gRPC server is expected to serve the HTTP/JSON // API directly. // // Example: // "localhost:8080" proxyAddr = flag.String("addr", ":8080", "The address to serve the proxy on") // // Example: // "localhost:9090" endpoint = flag.String("endpoint", "localhost:9090", "The upstream gRPC service endpoint") ) func run() error { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() // Register gRPC-Gateway mux := runtime.NewServeMux( // Use Marshaler option to customize JSON parsing. // For example, unmarshaling JSON with camelCase names to Protobuf // with snake_case names. runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ MarshalOptions: protojson.MarshalOptions{ UseProtoNames: true, EmitUnpopulated: true, }, UnmarshalOptions: protojson.UnmarshalOptions{ DiscardUnknown: true, }, }), ) // Connect to the gRPC server. conn, err := grpc.DialContext(ctx, *endpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return err } defer conn.Close() // Register the gRPC-Gateway handler service. // The following call is generated by protoc-gen-grpc-gateway. // It is not needed if you are using the grpc-gateway directly. // You may need to change the import path to match your project structure. // For example, if your proto files are in "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb", // you would use: // err = examplepb.RegisterYourServiceHandler(ctx, mux, conn) if err != nil { return err } // Start HTTP server. server := &http.Server{ Addr: *proxyAddr, Handler: mux, } // Start the server in a goroutine so that it doesn't block. go func() { if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { panic(err) } }() // Wait for interrupt signal to gracefully shut down the server. quit := make(chan os.Signal, 1) // kill (no param) default send syscall.SIGTERM // kill -2 is syscall.SIGINT // kill -9 is syscall.SIGKILL but don't want to catch this ssignal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit // Shutdown the server. return server.Shutdown(ctx) } func main() { flag.Parse() if err := run(); err != nil { panic(err) } } ``` -------------------------------- ### Install Tools from go.mod Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Install all tools declared in the go.mod file into the $GOBIN directory. ```sh go install tool ``` -------------------------------- ### Compile and Install gRPC-Gateway Service Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Compile and install the gRPC-Gateway service into the Go binary directory. This command finalizes the installation and makes the service executable. ```bash go install ``` -------------------------------- ### Install openapiv3-merge Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/openapiv3-merge/README.md Install the tool using the Go CLI. ```sh go install github.com/grpc-ecosystem/grpc-gateway/v2/openapiv3-merge@latest ``` -------------------------------- ### Install protoc-gen-openapiv3 Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/openapi_v3.md Install the protoc-gen-openapiv3 generator using the go install command. ```sh go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv3@latest ``` -------------------------------- ### Install Go Language Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Download and install the latest version of the Go language using the Windows installer. This is a prerequisite for gRPC-Gateway development. ```bash wget -N https://storage.googleapis.com/golang/go1.8.1.windows-amd64.msi msiexec /i go1.8.1.windows-amd64.msi /passive /promptrestart ``` -------------------------------- ### Install gRPC-Gateway Protoc Plugins Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/introduction.md Install the necessary protoc generator plugins for gRPC-Gateway, protobuf, and gRPC. Ensure $GOPATH/bin is in your $PATH. ```sh $ go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest $ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest ``` -------------------------------- ### CoreOS gRPC-Gateway Example Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/examples.md This Go code example demonstrates how to use the same port for custom HTTP handlers, gRPC-Gateway, and a gRPC server. It's useful for consolidating services on a single port. ```go package main import ( "context" "flag" "net/http" "os/signal" "syscall" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/coreos/go-oidc/oidc" "github.com/coreos/go-oidc/oidc/oidcclient" "github.com/golang/protobuf/ptypes/empty" "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb" ) var ( // command line only supports strings, so we have to cast from time.Duration. // This is a common pattern for command line flags. grpcEndpoint = flag.String("grpc-endpoint", "localhost:9090", "to gRPC server") port = flag.Int("port", 8080, "to gRPC server") ) func run() error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Register gRPC-Gateway mux := runtime.NewServeMux() err := examplepb.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *grpcEndpoint, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}) if err != nil { return err } // Register custom HTTP handlers mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World!")) }) // Start HTTP server. return http.ListenAndServe(":"+strconv.Itoa(*port), mux) } func main() { flag.Parse() // Setup graceful shutdown stopChan := make(chan os.Signal, 1) ssignal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM) go func() { if err := run(); err != nil { log.Fatal(err) } }() <-stopChan log.Println("Shutting down server...") } ``` -------------------------------- ### Register Custom Route with ServeMux Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/inject_router.md Register a custom HTTP GET route with a path parameter. This example shows how to handle a GET request to `/hello/{name}` and respond with a personalized message. ```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 } ``` -------------------------------- ### Proto File with Go Templates Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md An example proto file demonstrating the use of Go templates to inject custom arguments like environment details and method information into comments and service definitions. ```protobuf service LoginService { // Login (Environment: {{arg "environment_label"}}) // // {{.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}}". // This only works in the {{arg "environment"}} domain. // rpc Login (LoginRequest) returns (LoginReply) { option (google.api.http) = { post: "/v1/example/login" body: "*" }; } } ``` -------------------------------- ### Implement HTTP reverse-proxy entrypoint Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Create a Go main function to register the gRPC service handler and start the HTTP server. ```go package main import ( "context" "flag" "net/http" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/grpclog" gw "github.com/yourorg/yourrepo/proto/gen/go/your/service/v1/your_service" // Update ) var ( // 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.WithTransportCredentials(insecure.NewCredentials())} err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts) if err != nil { return err } // Start HTTP server (and proxy calls to gRPC server endpoint) return http.ListenAndServe(":8081", mux) } func main() { flag.Parse() if err := run(); err != nil { grpclog.Fatal(err) } } ``` -------------------------------- ### Build Bower and Backends for gRPC-Gateway Example Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/browser/README.md Runs specific build tasks for Bower and backends, typically preceding the opening of index.html. ```shell gulp bower gulp backends ``` -------------------------------- ### Configure buf.gen.yaml for OpenAPI v2 Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Example configuration for generating Go stubs and OpenAPI v2 definitions using buf. ```yaml version: v2 plugins: - local: protoc-gen-go out: gen/go opt: - paths=source_relative - local: protoc-gen-go-grpc out: gen/go opt: - paths=source_relative - local: protoc-gen-grpc-gateway out: gen/go opt: - paths=source_relative - generate_unbound_methods=true - local: protoc-gen-openapiv2 out: gen/go ``` -------------------------------- ### Proto File with Go Templates for Documentation Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Example proto file demonstrating the use of Go templates in comments to dynamically generate documentation, including importing external Markdown files and detailing RPC methods. ```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; } ``` -------------------------------- ### gRPC-Gateway Reverse Proxy Entrypoint Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/examples.md This Go file serves as the main entrypoint for the generated reverse proxy. It orchestrates the setup and startup of the gRPC-Gateway. ```go package main import ( "flag" "net/http" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" // This must be the same path as the import path for the "echo_service.pb.gw.go" file // generated from your "echo_service.proto" file. "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb" ) var ( // command line only supports strings, so we have to cast from time.Duration. // This is a common pattern for command line flags. endpoint = flag.String("url", "localhost:8080", "to gRPC server") ) func run() error { ctx := context.Background() mux := runtime.NewServeMux() // Register EchoService err := examplepb.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *endpoint, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}) if err != nil { return err } // Start HTTP server. return http.ListenAndServe(":8081", mux) } func main() { flag.Parse() if err := run(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Create gRPC Server in Go Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/creating_main.go.md This Go code sets up a gRPC server, defines a simple 'Greeter' service, and starts listening on TCP port 8080. Ensure your go.mod file is correctly configured. ```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)) } ``` -------------------------------- ### String Example Field in OpenAPI Annotations Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/grpc-gateway_v2_migration_guide.md The 'example' field in OpenAPI annotations is now a string, replacing the google.protobuf.Any type. Ensure any quotes within the string value are properly escaped. ```protobuf example: "{\"uuid\": \"0cf361e1-4b44-483d-a159-54dabdf7e814\"}" ``` -------------------------------- ### Install gRPC-Gateway runtime version Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Updates the project's go.mod to match the generator version used in remote plugins. ```shell $ go get github.com/grpc-ecosystem/grpc-gateway/v2@v2.16.2 ``` -------------------------------- ### Test Echo API with GET Request Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/README.md Send a GET request to the /v1/example/echo/{id}/{num} endpoint to test the echo functionality with an ID and number. ```bash $ curl http://localhost:8080/v1/example/echo/foo/123 {"id":"foo","num":"123"} ``` -------------------------------- ### Install Protocol Buffers Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Download and extract Protocol Buffers v3.2.0 for Windows. Ensure you use a version 3.0.0-beta-3 or later. This is required for generating protobuf code. ```bash 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/ ``` -------------------------------- ### Example Bash Script for OpenAPI Generation Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md This script demonstrates generating OpenAPI v2 specifications using `protoc`, enabling Go templates, and setting custom template arguments for environment-specific details. ```sh $protoc -I. \ --go_out . --go-grpc_out . \ --grpc-gateway_out . \ --openapiv2_out . \ --openapiv2_opt use_go_templates=true \ --openapiv2_opt go_template_args=environment=test1 \ --openapiv2_opt go_template_args=environment_label=Test1 \ path/to/my/proto/v1/myproto.proto ``` -------------------------------- ### Define HTTP Mapping with gRPC-Gateway Annotations Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/adding_annotations.md Import `google/api/annotations.proto` and use the `google.api.http` option to map RPC methods to HTTP paths and bodies. This example maps a POST request to `/v1/example/echo` to the `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; } ``` -------------------------------- ### Example cURL Command for Custom Header Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_your_gateway.md Demonstrates how to send a custom header using cURL, which can be matched by a custom header matcher. ```sh $ curl --header "x-user-id: 100d9f38-2777-4ee2-ac3b-b3a108f81a30" ... ``` -------------------------------- ### Protoc Command with Go Templates Enabled Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Example of a protoc command that enables Go templates for OpenAPI v2 generation, alongside other output options. ```sh $ protoc -I. \ --go_out . --go-grpc_out . \ --grpc-gateway_out . \ --openapiv2_out . \ --openapiv2_opt use_go_templates=true \ path/to/my/proto/v1/myproto.proto ``` -------------------------------- ### Wrapping Gateway Mux with Middleware Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/logging.md Example of how to integrate the logRequestBody middleware with a gRPC-Gateway runtime.NewServeMux. ```go mux := runtime.NewServeMux() // Register generated gateway handlers s := &http.Server{ Handler: logRequestBody(mux), } ``` -------------------------------- ### Upload binary file using curl Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/binary_file_uploads.md Example of uploading a binary file using curl. This demonstrates the client-side request format. ```sh curl -X POST -F "attachment=@/tmp/somefile.txt" http://localhost:9090/v1/files ``` -------------------------------- ### Configure buf.gen.yaml for remote plugins Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Defines remote plugins for Go and gRPC-Gateway generation without requiring local plugin installations. ```yaml version: v2 plugins: - remote: buf.build/protocolbuffers/go:v1.31.0 out: gen/go opt: - paths=source_relative - remote: buf.build/grpc/go:v1.3.0 out: gen/go opt: - paths=source_relative - remote: buf.build/grpc-ecosystem/gateway:v2.16.2 out: gen/go opt: - paths=source_relative - remote: buf.build/grpc-ecosystem/openapiv2:v2.16.2 out: gen/openapiv2 ``` -------------------------------- ### Manage Tool Dependencies with go get Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Add tools to the project module using the -tool flag to automatically update the go.mod file. ```sh go get -tool github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway go get -tool github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 go get -tool google.golang.org/protobuf/cmd/protoc-gen-go go get -tool google.golang.org/grpc/cmd/protoc-gen-go-grpc ``` -------------------------------- ### Manually add a span for a traced method Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/tracing.md Within a method, manually start a span using `trace.StartSpan`. Use `defer span.End()` to ensure the span is closed. Select an appropriate sampler. ```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. } ``` -------------------------------- ### Implement gRPC Health Watch Method Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/health_check.md Implement the Watch method for the gRPC Health Checking Protocol. This example shows how to register both methods but only implement the Check method, returning an unimplemented error for Watch. ```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") } ``` -------------------------------- ### Define HTTP Binding with Path Parameters Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Use `google.api.http` option to define GET requests with path parameters. Path parameters with multiple segments are automatically numbered to prevent duplicates. ```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; } ``` -------------------------------- ### Setup custom route for binary file upload Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/binary_file_uploads.md Configure a custom route on the gRPC Gateway mux instance to handle binary file uploads. This sets up a handler for POST requests to a specific path. ```go // Create a mux instance mux := runtime.NewServeMux() // Attachment upload from http/s handled manually mux.HandlePath("POST", "/v1/files", handleBinaryFileUpload) ``` -------------------------------- ### Resolve Go Get Errors During Project Build Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Manually clone required Go packages into the correct source directories to fix `go get` errors encountered when building the project. This is similar to the installation fix but for project-specific dependencies. ```bash 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 git clone https://github.com/grpc/grpc-go $(cygpath -u $GOPATH)/src/google.golang.org/grpc ``` -------------------------------- ### Initialize Project Dependencies Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/README.md Use 'dep init' to initialize project dependencies for Go. ```bash # Handle dependencies $ dep init ``` -------------------------------- ### Fix Git Clone Destinations for Go Get Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Manually clone repositories into the correct Go workspace paths to resolve `go get` failures caused by incorrect path handling in Cygwin. This ensures dependencies are downloaded properly. ```bash 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/protobuf $(cygpath -u $GOPATH)/src/github.com/golang/protobuf git clone https://github.com/google/go-genproto $(cygpath -u $GOPATH)/src/google.golang.org/genproto ``` -------------------------------- ### Example openapiv3-merge error output Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/openapi_v3_merge.md The error message format displayed when a field conflict occurs during the merge process. ```text openapiv3-merge: paths."/v1/echo": echo.openapi.json redefines an entry with a different value ``` -------------------------------- ### Initialize a Go Module Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/introduction.md Initialize a new Go module using 'go mod init'. Replace 'github.com/myuser/myrepo' with your module's path. This creates a go.mod file to manage dependencies. ```sh $ go mod init github.com/myuser/myrepo go: creating new go.mod: module github.com/myuser/myrepo ``` -------------------------------- ### Create Go Workspace Directories Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Set up the necessary directories for your Go workspace. This structure is standard for Go projects and helps organize source code, compiled packages, and binaries. ```bash mkdir /home/user/go mkdir /home/user/go/bin mkdir /home/user/go/pkg mkdir /home/user/go/src ``` -------------------------------- ### Implement gRPC and gRPC-Gateway Server in Go Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/adding_annotations.md This Go program sets up a gRPC server and a gRPC-Gateway multiplexer. The gateway proxies HTTP requests to the gRPC server, allowing you to interact with your gRPC service via RESTful APIs. ```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.NewClient( "0.0.0.0:8080", 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()) } ``` -------------------------------- ### Enable Go Templates and Provide Arguments Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Use `use_go_templates=true` to enable Go templates and `go_template_args` to pass custom key-value pairs that can be accessed within the templates using `{{arg "key"}}`. ```sh --openapiv2_out . --openapiv2_opt use_go_templates=true --openapiv2_opt go_template_args=my_key1=my_value1 --openapiv2_opt go_template_args=my_key2=my_value2 ``` -------------------------------- ### Example cURL Command for Case-Insensitive Custom Header Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_your_gateway.md Shows sending a custom header with different casing, illustrating the potential for case-insensitive matching. ```sh $ curl --header "X-USER-ID: 100d9f38-2777-4ee2-ac3b-b3a108f81a30" ... ``` -------------------------------- ### Run Buf Generate Command Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/generating_stubs/using_buf.md Execute the buf generate command to create *.pb.go and *_grpc.pb.go files for each protobuf package. ```sh $ buf generate ``` -------------------------------- ### gRPC Server Implementation Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/examples.md This Go file contains the implementation of the gRPC service. It defines the actual logic that the gRPC server will execute. ```go package main import ( "context" "log" "net" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "github.com/grpc-ecosystem/grpc-gateway/examples/internal/proto/examplepb" ) const ( port = "8080" ) // server is used to implement examplepb.EchoServiceServer. type server struct { examplepb.UnimplementedEchoServiceServer } // SayHello implements examplepb.EchoServiceServer func (s *server) SayHello(ctx context.Context, in *examplepb.HelloRequest) (*examplepb.HelloReply, error) { log.Printf("Received: %v", in.GetName()) return &examplepb.HelloReply{Message: "Hello " + in.GetName()}, } func main() { lis, err := net.Listen("tcp", ":"+port) if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer := grpc.NewServer() examplepb.RegisterEchoServiceServer(grpcServer, &server{}) reflection.Register(grpcServer) log.Printf("server listening at %v", lis.Addr()) if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } ``` -------------------------------- ### Implement custom stream delimiter Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/custom_marshalers.md Implement the Delimited interface to change the delimiter for streamed responses. This example sets the delimiter to a pipe character. ```go type YourMarshaler struct { // ... } // ... func (*YourMarshaler) Delimiter() []byte { return []byte("|") } ``` -------------------------------- ### Generate gRPC-Gateway Stubs with buf Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/adding_annotations.md Run the `buf generate` command after configuring your `buf.yaml` to generate the `*.gw.pb.go` files. ```sh $ buf generate ``` -------------------------------- ### Set GOPATH and Update PATH Environment Variables Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/development/installation_for_cygwin.md Configure the GOPATH environment variable and add the Go binary directory to your system's PATH. Use `reg add` for PATH modification to avoid truncation issues with `setx`. ```bash setx GOPATH c:\path\to\your\cygwin\home\user\go /M set pathkey="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" for /F "usebackq skip=2 tokens=2*" %A IN (`reg query %pathkey% /v Path`) do (reg add %pathkey% /f /v Path /t REG_SZ /d "%B;c:\path\to\your\cygwin\home\user\go\bin") ``` -------------------------------- ### Generate gRPC stubs with protoc Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Execute the protoc command to generate Go stubs manually. ```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 ``` -------------------------------- ### Generated OpenAPI for Deprecated RPC Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Example of generated OpenAPI output for a deprecated RPC. The `deprecated: true` field is added to the RPC definition in the paths section. ```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 deprecated: true 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: type: object $ref: '#/definitions/protobufAny' v1HelloResp: type: object properties: message: type: string ``` -------------------------------- ### Passing Plugin Options via protoc CLI Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Demonstrates how to pass multiple OpenAPI v2 plugin options as comma-separated values directly on the `protoc` command line. ```sh --openapiv2_out . --openapiv2_opt bar=baz,color=red ``` -------------------------------- ### Configure buf.gen.yaml for code generation Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Define plugins and options for generating Go and gRPC-Gateway stubs. ```yaml version: v2 plugins: - local: protoc-gen-go out: gen/go opt: - paths=source_relative - local: protoc-gen-go-grpc out: gen/go opt: - paths=source_relative - local: protoc-gen-grpc-gateway out: gen/go opt: - paths=source_relative ``` ```yaml version: v2 plugins: - local: protoc-gen-go out: gen/go opt: - paths=source_relative - local: protoc-gen-go-grpc out: gen/go opt: - paths=source_relative - local: protoc-gen-grpc-gateway out: gen/go opt: - paths=source_relative - grpc_api_configuration=path/to/config.yaml - standalone=true ``` -------------------------------- ### Customize Unmarshaling per Content-Type Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_your_gateway.md Configure specific unmarshaling options for a given MIME type by registering a custom marshaler. This example sets `DiscardUnknown` to `false` for `application/json+strict`. ```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 }, }), ) ``` -------------------------------- ### gRPC-Gateway Custom Response Rewriting Setup Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_your_gateway.md Configure gRPC-Gateway with both a forward response option to set status codes and a response rewriter to customize the response body structure. ```go mux := runtime.NewServeMux( runtime.WithForwardResponseOption(setStatus), runtime.WithForwardResponseRewriter(responseEnvelope), ) ``` -------------------------------- ### Configure gRPC-Gateway with buf Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Use the opt field in buf.gen.yaml to pass generation parameters when using buf. ```yaml version: v2 plugins: - local: protoc-gen-grpc-gateway out: gen/go opt: - paths=source_relative - grpc_api_configuration=path/to/config.yaml - standalone=true ``` -------------------------------- ### Implement custom stream content type for NDJSON Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/custom_marshalers.md Implement the StreamContentType method to specify a distinct content type for stream responses, such as application/x-ndjson. This example wraps the JSONPb marshaler. ```go type CustomJSONPb struct { runtime.JSONPb } func (*CustomJSONPb) Delimiter() []byte { // Strictly speaking this is already the default delimiter for JSONPb, but // providing it here for completeness with an NDJSON marshaler all in one // place. return []byte("\n") } func (*CustomJSONPb) StreamContentType(interface{}) string { return "application/x-ndjson" } ``` -------------------------------- ### Define gRPC Service with Protocol Buffers Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/simple_hello_world.md Define the Greeter service, HelloRequest, and HelloReply messages using proto3 syntax. This file serves as the contract for your gRPC service. ```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; } ``` -------------------------------- ### Customize OpenAPI Schema for Enums Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Customize OpenAPI definitions for enums using the `openapiv2_enum` option. This allows setting descriptions, titles, extensions, external documentation, and examples for enum values. ```protobuf // NumericEnum is one or zero. enum NumericEnum { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_enum) = { description: "NumericEnum is one or zero." title: "NumericEnum" extensions: { key: "x-a-bit-of-everything-foo" value { string_value: "bar" } } external_docs: { url: "https://github.com/grpc-ecosystem/grpc-gateway" description: "Find out more about ABitOfEverything" } example: "\"ZERO\"" }; // ZERO means 0 ZERO = 0; // ONE means 1 ONE = 1; } ``` -------------------------------- ### Generate Go gRPC Stubs with protoc Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/tutorials/generating_stubs/using_protoc.md Use this command to generate Go types and gRPC service definitions from a proto file. Ensure you are in the repository root and proto files are in the `./proto` directory. The `paths=source_relative` option places generated files alongside their source. ```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 ``` -------------------------------- ### Custom Routing Error Handler Implementation Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_your_gateway.md An example custom routing error handler that preserves '405 Method Not Allowed' errors by mapping them to `codes.Unimplemented` and then using the default HTTP error handler. ```go func handleRoutingError(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) { if httpStatus != http.StatusMethodNotAllowed { runtime.DefaultRoutingErrorHandler(ctx, mux, marshaler, w, r, httpStatus) return } // Use HTTPStatusError to customize the DefaultHTTPErrorHandler status code err := &runtime.HTTPStatusError{ HTTPStatus: httpStatus, Err: status.Error(codes.Unimplemented, http.StatusText(httpStatus)), } runtime.DefaultHTTPErrorHandler(ctx, mux, marshaler, w, r, err) } ``` -------------------------------- ### Verify Release Binary with SLSA Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/README.md Use the slsa-verifier tool to ensure the integrity of downloaded release binaries against provenance files. ```shell slsa-verifier -artifact-path -provenance attestation.intoto.jsonl -source github.com/grpc-ecosystem/grpc-gateway -tag ``` -------------------------------- ### Apply global tracing configuration Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/tracing.md Set the default sampler for tracing. 'AlwaysSample()' traces all requests; consider 'trace.ProbabilitySampler()' for production. ```go // Always trace in this example. // In production this can be set to a trace.ProbabilitySampler. trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) ``` -------------------------------- ### cURL Example: PATCH (FieldMask Hidden) Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/patch_feature.md Demonstrates a cURL command to perform a partial update using the PATCH method when the FieldMask is hidden from the REST request. Only the specified field ('stringValue') is updated. ```sh $ curl \ --data '{"stringValue": "strprefix/foo"}' \ -X PATCH \ http://address:port/v2/example/a_bit_of_everything/1 ``` -------------------------------- ### Import necessary packages for tracing Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/operations/tracing.md Add these imports to enable tracing functionality with OpenCensus and AWS X-ray. ```go xray "contrib.go.opencensus.io/exporter/aws" "go.opencensus.io/plugin/ocgrpc" "go.opencensus.io/plugin/ochttp" "go.opencensus.io/trace" ``` -------------------------------- ### Enable Go Templates in Protoc Command Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Enable Go template functionality for advanced proto file comment documentation by adding the `use_go_templates=true` option to the protoc command. ```sh --openapiv2_out . --openapiv2_opt use_go_templates=true ``` ```sh --openapiv2_out=use_go_templates=true:. ``` -------------------------------- ### Add Swagger Extensions Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Add custom Swagger Extensions to OpenAPI definitions by using the `extensions` field within proto options. Keys must start with `x-`, and values can be of various protobuf types. ```protobuf extensions: { key: "x-amazon-apigateway-authorizer"; value { struct_value { fields { key: "type"; value { string_value: "token"; } } fields { key: "authorizerResultTtlInSeconds"; value { number_value: 60; } } } } } ``` -------------------------------- ### gRPC Proto Definition with HTTP Annotations Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md A sample protobuf definition including service and message definitions with gRPC-to-HTTP mapping annotations. ```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; } ``` -------------------------------- ### Configuring Plugin Options with buf.gen.yaml Source: https://github.com/grpc-ecosystem/grpc-gateway/blob/main/docs/docs/mapping/customizing_openapi_output.md Shows how to specify OpenAPI v2 plugin options within a `buf.gen.yaml` configuration file using the `opt` field. ```yaml - name: openapiv2 out: foo opt: bar=baz,color=red ```