Reputation: 383
I'm currently new to gRPC technology and have been reading up on it.
My current understanding is that gRPC
is just another protocol just like how REST
is one. Now lets say I spin up a gRPC server that I want clients to consume, but in that gRPC server I'd like to be able to get information from outside consumer RESTful Apis, (for example https://developer.riotgames.com/api-methods/) is that still possible?
Upvotes: 1
Views: 9932
Reputation: 1771
Yes, it is possible. You can make calls to other APIs and services from your own gRPC service code.
Just let your client make a call to your gRPC service. Then, your service makes a REST call to external API (possibly using arguments from client request to your gRPC service) and processes it. Return the result to your client however your gRPC service responds.
Upvotes: 2
Reputation: 1161
You would need to use grcp-gateway
to generate proxy full code available on go-grpc-tutorial thanks to phuongdo
install deps:
$sudo apt install libprotobuf-dev
go get google.golang.org/grpc
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
define service, pb/service.proto:
syntax = "proto3";
option go_package = "echo";
package echo;
import "google/api/annotations.proto";
//Message represents a simple message sent to the Echo service.
message Message {
string id = 1;
string msg = 2;
}
//Echo service responds to incoming echo requests.
service EchoService {
//Echo method receives a simple message and returns it.
//The message posted as the id parameter will also be returned.
rpc Echo(Message) returns (Message) {
option (google.api.http) = {
post: "/v1/example/echo/{id}/{msg}"
};
}
}
generate stub for server and clinet
$ protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-
gateway/third_party/googleapis \
--go_out=google/api/annotations.proto=github.com/grpc-ecosystem/grpc-
gateway/third_party/googleapis/google/api,plugins=grpc:. \
pb/service.proto
and reverse proxy
for REST API
$ protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-
gateway/third_party/googleapis \
--grpc-gateway_out=logtostderr=true:. \
pb/service.proto
server/server.go:
package main
import (
"flag"
"github.com/golang/glog"
pb "github.com/go-grpc-tutorial/pb"
"golang.org/x/net/context"
"google.golang.org/grpc"
"net"
)
// Implements of EchoServiceServer
type echoServer struct{}
func newEchoServer() pb.EchoServiceServer {
return new(echoServer)
}
func (s *echoServer) Echo(ctx context.Context, msg *pb.Message)
(*pb.Message, error) {
glog.Info(msg)
return msg, nil
}
func Run() error {
listen, err := net.Listen("tcp", ":50051")
if err != nil {
return err
}
server := grpc.NewServer()
pb.RegisterEchoServiceServer(server, newEchoServer())
server.Serve(listen)
return nil
}
func main() {
flag.Parse()
defer glog.Flush()
if err := Run(); err != nil {
glog.Fatal(err)
}
}
write rest api, server/server-rproxy.go:
package main
import (
"flag"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/golang/glog"
pb "github.com/go-grpc-tutorial/pb"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
var (
echoEndpoint = flag.String("echo_endpoint", "localhost:50051",
"endpoint of EchoService")
)
func RunEndPoint(address string, opts ...runtime.ServeMuxOption)
error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux(opts...)
dialOpts := []grpc.DialOption{grpc.WithInsecure()}
err := pb.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, dialOpts)
if err != nil {
return err
}
http.ListenAndServe(address, mux)
return nil
}
func main() {
flag.Parse()
defer glog.Flush()
if err := RunEndPoint(":8080"); err != nil {
glog.Fatal(err)
}
}
build client server/client.go:
package main
import (
"log"
"os"
"golang.org/x/net/context"
"google.golang.org/grpc"
pb "github.com/go-grpc-tutorial/pb"
)
const (
address = "localhost:50051"
defaultName = "PhuongDV"
)
func main() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewEchoServiceClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
r, err := c.Echo(context.Background(), &pb.Message{Id: "1", Msg: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Msg)
}
finally run server, client, rest and call rest:
$ go run server/server.go
$ go run client/client.go
$go run server/server-rproxy.go
$ curl -X POST "http://localhost:8080/v1/example/echo/1/PhuongDV"
1: https://github.com/phuongdo/go-grpc-tutorial 2: https://i.sstatic.net/C4s7s.png
Upvotes: 0