forked from grpc-ecosystem/grpc-gateway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GSoD] Added tutorials directory on gRPC-Gateway (grpc-ecosystem#1829)
* added tutorials directory on grpc-gateway * refactored badges and links * added requested changes * updated tutorials directory on grpc-gateway * updated tutorials directory on grpc-gateway * updated tutorials directory on grpc-gateway * updated tutorials * updated tutorials * updated tutorials * updated tutorials * updated headings and added next button for tutorials * updated next buttons * updated tutorials * updated tutorials * updated tutorials * updated tutorials * updated tutorials * updated tutorials * added helloworld link
- Loading branch information
Showing
11 changed files
with
460 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
--- | ||
layout: default | ||
title: FAQ | ||
nav_order: 7 | ||
nav_order: 8 | ||
--- | ||
|
||
# FAQ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
--- | ||
layout: default | ||
title: Adding the grpc-gateway annotations to an existing protobuf file | ||
parent: Tutorials | ||
nav_order: 5 | ||
--- | ||
|
||
# Adding the grpc-gateway annotations to an existing protobuf 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. | ||
|
||
```proto | ||
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. | ||
|
||
Before we can do that, we need to copy some dependencies into our protofile structure. Copy the `third_party/googleapis` folder from the grpc-gateway repository to your local protofile structure. It should look like this afterwards: | ||
|
||
``` | ||
proto | ||
│ └── api | ||
│ ├── annotations.proto | ||
│ └── http.proto | ||
└── helloworld | ||
└── hello_world.proto | ||
``` | ||
|
||
### Using buf | ||
|
||
We'll need to add the grpc-gateway generator to the generation configuration: | ||
|
||
```yml | ||
version: v1beta1 | ||
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 | ||
``` | ||
And that's it! Now if you run: | ||
```sh | ||
$ buf generate | ||
``` | ||
|
||
It should produce a `*.gw.pb.go` file. | ||
|
||
### Using protoc | ||
|
||
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" | ||
|
||
helloworldpb "github.com/myuser/myrepo/proto/helloworld" | ||
) | ||
|
||
type server struct{} | ||
|
||
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.WithInsecure(), | ||
) | ||
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 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 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
layout: default | ||
title: Creating main.go | ||
parent: Tutorials | ||
nav_order: 4 | ||
--- | ||
|
||
# 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{} | ||
|
||
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 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
layout: default | ||
title: Generating stubs | ||
parent: Tutorials | ||
nav_order: 3 | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
layout: default | ||
title: Generating stubs using buf | ||
parent: Generating stubs | ||
grand_parent: Tutorials | ||
nav_order: 1 | ||
--- | ||
|
||
# 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 repository. 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. | ||
|
||
All Buf operations that use your local `.proto` files as input rely on a valid build configuration. This configuration tells Buf where to search for `.proto` files, and how to handle imports. 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, assuming you have your `.proto` files rooted in the `proto` folder relative to the root of your repository. | ||
|
||
```yml | ||
version: v1beta1 | ||
build: | ||
roots: | ||
- proto | ||
``` | ||
To generate type and gRPC stubs for Go, create the file `buf.gen.yaml` at the root of the repository: | ||
|
||
```yml | ||
version: v1beta1 | ||
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 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
layout: default | ||
title: Generating stubs using protoc | ||
parent: Generating stubs | ||
grand_parent: Tutorials | ||
nav_order: 2 | ||
--- | ||
|
||
# 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 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
layout: default | ||
title: Tutorials | ||
nav_order: 7 | ||
has_children: true | ||
--- |
Oops, something went wrong.