Skip to content

Instantly share code, notes, and snippets.

@anandsunderraman
Created February 4, 2021 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anandsunderraman/eba92b2e97edaffac83503c2de5fa1a0 to your computer and use it in GitHub Desktop.
Save anandsunderraman/eba92b2e97edaffac83503c2de5fa1a0 to your computer and use it in GitHub Desktop.
Using grpcurl as a library
package main
import (
"bytes"
"fmt"
"github.com/fullstorydev/grpcurl"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/status"
"os"
"strings"
"time"
)
var ctx = context.Background()
//this is a modified version of the inline
//dial function in https://github.com/fullstorydev/grpcurl/blob/master/grpcurl.go
func dial(target string) *grpc.ClientConn {
dialTime := 10 * time.Second
ctx, cancel := context.WithTimeout(ctx, dialTime)
defer cancel()
var opts []grpc.DialOption
var creds credentials.TransportCredentials
grpcurlUA := "grpcurl/dev-build (no version set)"
opts = append(opts, grpc.WithUserAgent(grpcurlUA))
network := "tcp"
cc, err := grpcurl.BlockingDial(ctx, network, target, creds, opts...)
if err != nil {
fmt.Printf( "Failed to dial target host %s", target)
}
return cc
}
func main() {
//proto file names
fileNames := "service.proto"
//import paths for the proto file
importPaths := []string{"./"}
//the combination of service.method to be invoked
symbol := "<service>.<method>"
//address of the gRPC service
address := "localhost:8080"
//parsing the proto file information
fileSource, err := grpcurl.DescriptorSourceFromProtoFiles(importPaths, fileNames)
if err != nil {
fmt.Print(err)
}
var cc *grpc.ClientConn
cc = dial(address)
verbosityLevel := 0
includeSeparators := verbosityLevel == 0
options := grpcurl.FormatOptions{
EmitJSONDefaultFields: false,
IncludeTextSeparator: includeSeparators,
AllowUnknownFields: false,
}
payload := "your payload as json"
rf, formatter, err := grpcurl.RequestParserAndFormatter("json", fileSource, strings.NewReader(payload), options)
if err != nil {
fmt.Print(err)
}
//reading the result into a string
var output bytes.Buffer
h := &grpcurl.DefaultEventHandler{
Out: &output,
Formatter: formatter,
VerbosityLevel: verbosityLevel,
}
//actual invocation of the gRPC call
err = grpcurl.InvokeRPC(ctx, fileSource, cc, symbol, nil, h, rf.Next)
if err != nil {
if errStatus, ok := status.FromError(err); ok {
h.Status = errStatus
} else {
fmt.Printf("Error invoking method %s, error is: %s", symbol, err)
}
}
if h.Status.Code() != codes.OK {
grpcurl.PrintStatus(os.Stderr, h.Status, formatter)
}
//printing the result
fmt.Print(output.String())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment