by Edgar Sipki
syntax = "proto3";
package your.service.v1;
option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
message StringMessage {
string value = 1;
}
service YourService {
rpc Echo(StringMessage) returns (StringMessage) {}
}
syntax = "proto3";
package your.service.v1;
option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
import "google/api/annotations.proto";
message StringMessage {
string value = 1;
}
service YourService {
rpc Echo(StringMessage) returns (StringMessage) {
option (google.api.http) = {
post: "/v1/example/echo"
body: "*"
};
}
}
/v1/example/echo
address and process them as gRPC calls. This is an example of how gRPC-Gateway simplifies life for developers by providing a single, universally understandable API.package main
import (
"context"
"log"
"net"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
echo "path/to/your/protobuf_package"
)
const (
grpcServerEndpoint = "localhost:50051"
httpServerEndpoint = "localhost:8080"
)
type EchoService struct {
echo.UnimplementedEchoServiceServer
}
func (s *EchoService) Echo(ctx context.Context, in *echo.EchoRequest) (*echo.EchoResponse, error) {
return &echo.EchoResponse{Message: "Echo: " + in.Message}, nil
}
func main() {
g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error {
return startGRPCServer(ctx)
})
g.Go(func() error {
return startHTTPServer(ctx)
})
if err := g.Wait(); err != nil {
log.Fatalf("Failed to start servers: %s", err)
}
}
func startGRPCServer(ctx context.Context) (err error) {
lis, err := net.Listen("tcp", grpcServerEndpoint)
if err != nil {
return err
}
s := grpc.NewServer()
echo.RegisterEchoServiceServer(s, &EchoService{})
go func() {
<-ctx.Done()
s.GracefulStop()
}()
log.Printf("Starting gRPC server on %s", grpcServerEndpoint)
return s.Serve(lis)
}
func startHTTPServer(ctx context.Context) (err error) {
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
err = echo.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, grpcServerEndpoint, opts)
if err != nil {
return err
}
srv := &http.Server{
Addr: httpServerEndpoint,
Handler: mux,
}
go func() {
<-ctx.Done()
srv.Shutdown(ctx)
}()
log.Printf("Starting HTTP server on %s", httpServerEndpoint)
return srv.ListenAndServe()
}