https://github.com/tembleking/test-grpc-gateway
https://github.com/tembleking/test-grpc-gateway
Last synced: 9 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/tembleking/test-grpc-gateway
- Owner: tembleking
- Created: 2022-08-12T11:07:14.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2025-06-03T16:43:35.000Z (about 1 year ago)
- Last Synced: 2025-06-14T05:03:04.080Z (about 1 year ago)
- Language: Go
- Size: 43.9 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Test of gRPC-gateway
This is a POC of a server listening to both HTTP and gRPC with autogenerated server and client implementations, and swagger documentation.
## Protobuf definition
The definition is stored in `pkg/application/proto/service.proto`. It has some annotations for swagger documentation, but the definition is as minimum as follows:
```protobuf
syntax = "proto3";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
option go_package = "github.com/tembleking/test-grpc-gateway/pkg/application/proto";
// The description of the test service
service TestService {
// The description of the method
rpc Test(google.protobuf.Empty) returns (TestResponse) {
option (google.api.http) = {
get: "/test"
};
}
}
// TestResponse is the response message for the Test method.
message TestResponse {
// Message is the test message.
string message = 1;
}
```
As you can see this is a minimum hello world service that will listen to `/test` and will return a response with a `message` field.
The three files in `pkg/application/proto/.*pb.*go` are autogenerated. The other three `pkg/application/proto/buf.*` files are for [`buf`](https://buf.build) to generate the code.
## Swagger documentation
The swagger definition is automatically generated in `pkg/application/http/docs/swagger.swagger.yaml`.
## HTTP server
The HTTP router implementation in `pkg/application/http/router.go` just registers the endpoints defined in the Proto definition and will redirect them to the gRPC server:
```go
options := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
err := proto.RegisterTestServiceHandlerFromEndpoint(ctx, mux, grpcListenAddress, options)
```
## gRPC server
The gRPC server is implemented in `pkg/application/grpc/grpc.go`. Contains the actual logic that will be executed in the application.
In case of an HTTP request to `/test`, this will be processed here as well.
```go
type server struct {
}
func (s *server) Test(ctx context.Context, empty *emptypb.Empty) (*proto.TestResponse, error) {
return &proto.TestResponse{Message: "Hello world!"}, nil
}
func NewServer() *grpc.Server {
grpcServer := grpc.NewServer()
server := &server{}
proto.RegisterTestServiceServer(grpcServer, server)
reflection.Register(grpcServer)
return grpcServer
}
```
It will just answer with a `TestResponse` with a `message` field set to `Hello world!`.
## Execution
The server can be launched with `go run ./cmd/test-grpc-gateway/`. It will listen to both HTTP and gRPC on `:8080` and `:9090`.
### HTTP Request
If you perform an HTTP request to `/test`, you will get the response:
```
$ http localhost:8080/test
HTTP/1.1 200 OK
Content-Length: 26
Content-Type: application/json
Date: Fri, 12 Aug 2022 10:33:30 GMT
Grpc-Metadata-Content-Type: application/grpc
{
"message": "Hello world!"
}
```
### gRPC Request
There is a gRPC client implementation in `cmd/grpc-client/` that uses the autogenerated code in `pkg/application/proto` that
will contact the server on `:9090`.
```go
func main() {
conn, err := grpc.Dial("localhost:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil { ... }
defer conn.Close()
client := proto.NewTestServiceClient(conn)
response, err := client.Test(context.Background(), &emptypb.Empty{})
if err != nil { ... }
log.Printf("%s", response.Message)
}
```
After executing it, with the server listening, you should see the following:
```
$ go run ./cmd/grpc-client/
2022/08/12 10:33:30 Hello world!
```