github.com/grpc-ecosystem/grpc-gateway/v2@v2.19.1/docs/docs/tutorials/adding_annotations.md (about)

     1  ---
     2  layout: default
     3  title: Adding gRPC-Gateway annotations to an existing proto file
     4  nav_order: 4
     5  parent: Tutorials
     6  ---
     7  
     8  # Adding gRPC-Gateway annotations to an existing proto file
     9  
    10  Now that we've got a working Go gRPC server, we need to add the gRPC-Gateway annotations.
    11  
    12  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.
    13  
    14  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.
    15  
    16  ```protobuf
    17  syntax = "proto3";
    18  
    19  package helloworld;
    20  
    21  import "google/api/annotations.proto";
    22  
    23  // Here is the overall greeting service definition where we define all our endpoints
    24  service Greeter {
    25    // Sends a greeting
    26    rpc SayHello (HelloRequest) returns (HelloReply) {
    27      option (google.api.http) = {
    28        post: "/v1/example/echo"
    29        body: "*"
    30      };
    31    }
    32  }
    33  
    34  // The request message containing the user's name
    35  message HelloRequest {
    36    string name = 1;
    37  }
    38  
    39  // The response message containing the greetings
    40  message HelloReply {
    41    string message = 1;
    42  }
    43  ```
    44  
    45  See [a_bit_of_everything.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/proto/examplepb/a_bit_of_everything.proto) for examples of more annotations you can add to customize gateway behavior.
    46  
    47  ## Generating the gRPC-Gateway stubs
    48  
    49  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.
    50  
    51  ### Using buf
    52  
    53  We'll need to add the gRPC-Gateway generator to the generation configuration:
    54  
    55  ```yaml
    56  version: v1
    57  plugins:
    58    - plugin: go
    59      out: proto
    60      opt: paths=source_relative
    61    - plugin: go-grpc
    62      out: proto
    63      opt: paths=source_relative,require_unimplemented_servers=false
    64    - plugin: grpc-gateway
    65      out: proto
    66      opt: paths=source_relative
    67  ```
    68  
    69  We'll also need to add the `googleapis` dependency to our `buf.yaml` file:
    70  
    71  ```yaml
    72  version: v1
    73  name: buf.build/myuser/myrepo
    74  deps:
    75    - buf.build/googleapis/googleapis
    76  ```
    77  
    78  Then we need to run `buf mod update` to select a version of the dependency to use.
    79  
    80  And that's it! Now if you run:
    81  
    82  ```sh
    83  $ buf generate
    84  ```
    85  
    86  It should produce a `*.gw.pb.go` file.
    87  
    88  ### Using `protoc`
    89  
    90  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`
    91  from the [official repository](https://github.com/googleapis/googleapis) to your local proto file structure. It should look like this afterwards:
    92  
    93  ```
    94  proto
    95  ├── google
    96  │   └── api
    97  │       ├── annotations.proto
    98  │       └── http.proto
    99  └── helloworld
   100      └── hello_world.proto
   101  ```
   102  
   103  Now we need to add the gRPC-Gateway generator to the `protoc` invocation:
   104  
   105  ```sh
   106  $ protoc -I ./proto \
   107    --go_out ./proto --go_opt paths=source_relative \
   108    --go-grpc_out ./proto --go-grpc_opt paths=source_relative \
   109    --grpc-gateway_out ./proto --grpc-gateway_opt paths=source_relative \
   110    ./proto/helloworld/hello_world.proto
   111  ```
   112  
   113  This should generate a `*.gw.pb.go` file.
   114  
   115  We also need to add and serve the gRPC-Gateway mux in our `main.go` file.
   116  
   117  ```go
   118  package main
   119  
   120  import (
   121  	"context"
   122  	"log"
   123  	"net"
   124  	"net/http"
   125  
   126  	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
   127  	"google.golang.org/grpc"
   128  	"google.golang.org/grpc/credentials/insecure"
   129  
   130  	helloworldpb "github.com/myuser/myrepo/proto/helloworld"
   131  )
   132  
   133  type server struct{
   134  	helloworldpb.UnimplementedGreeterServer
   135  }
   136  
   137  func NewServer() *server {
   138  	return &server{}
   139  }
   140  
   141  func (s *server) SayHello(ctx context.Context, in *helloworldpb.HelloRequest) (*helloworldpb.HelloReply, error) {
   142  	return &helloworldpb.HelloReply{Message: in.Name + " world"}, nil
   143  }
   144  
   145  func main() {
   146  	// Create a listener on TCP port
   147  	lis, err := net.Listen("tcp", ":8080")
   148  	if err != nil {
   149  		log.Fatalln("Failed to listen:", err)
   150  	}
   151  
   152  	// Create a gRPC server object
   153  	s := grpc.NewServer()
   154  	// Attach the Greeter service to the server
   155  	helloworldpb.RegisterGreeterServer(s, &server{})
   156  	// Serve gRPC server
   157  	log.Println("Serving gRPC on 0.0.0.0:8080")
   158  	go func() {
   159  		log.Fatalln(s.Serve(lis))
   160  	}()
   161  
   162  	// Create a client connection to the gRPC server we just started
   163  	// This is where the gRPC-Gateway proxies the requests
   164  	conn, err := grpc.DialContext(
   165  		context.Background(),
   166  		"0.0.0.0:8080",
   167  		grpc.WithBlock(),
   168  		grpc.WithTransportCredentials(insecure.NewCredentials()),
   169  	)
   170  	if err != nil {
   171  		log.Fatalln("Failed to dial server:", err)
   172  	}
   173  
   174  	gwmux := runtime.NewServeMux()
   175  	// Register Greeter
   176  	err = helloworldpb.RegisterGreeterHandler(context.Background(), gwmux, conn)
   177  	if err != nil {
   178  		log.Fatalln("Failed to register gateway:", err)
   179  	}
   180  
   181  	gwServer := &http.Server{
   182  		Addr:    ":8090",
   183  		Handler: gwmux,
   184  	}
   185  
   186  	log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090")
   187  	log.Fatalln(gwServer.ListenAndServe())
   188  }
   189  ```
   190  
   191  For more examples, please refer to [our boilerplate repository](https://github.com/johanbrandhorst/grpc-gateway-boilerplate).
   192  
   193  ## Testing the gRPC-Gateway
   194  
   195  Now we can start the server:
   196  
   197  ```sh
   198  $ go run main.go
   199  ```
   200  
   201  Then we use cURL to send HTTP requests:
   202  
   203  ```sh
   204  $ curl -X POST -k http://localhost:8090/v1/example/echo -d '{"name": " hello"}'
   205  ```
   206  
   207  ```
   208  {"message":"hello world"}
   209  ```
   210  
   211  Hopefully, that gives a bit of understanding of how to use the gRPC-Gateway.
   212  
   213  Full source code of hello world program can be found here [helloworld-grpc-gateway](https://github.com/iamrajiv/helloworld-grpc-gateway).
   214  
   215  [Next](learn_more.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }