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 }