Reputation: 1530
I have added below new code in protobuf file and compiled to get the generated grpc_pb files.
service EchoService {
rpc Echo(EchoMessage) returns (EchoMessage) {
#-----New code start-----
option (google.api.http) = {
post: "/v1/echo"
body: "*"
};
#-----New code end------
}
}
From cURL command executed below command
curl -X POST -k https://localhost:10000/v1/echo -d '{"Key": "Value"}'
After making above request, not able to get the proper response.
My doubt is, any server side code changes needed to prepare the response to send back to caller? If so, Please suggest me with the code (Java) & also how to make request. If not, how we need to make http request to grpc?
Working example is much appreciated.
Upvotes: 15
Views: 67467
Reputation: 58144
There's no obligation to use grpcurl
(although it is a handy tool). If you're stubborn like me and want to use curl
, or want to learn the gRPC protocol (per the spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), here's how to do the example above:
printf '\x00\x00\x00\x00\x04\x0a\x05\x56\x61\x6c\x75\x65' | \
curl --http2-prior-knowledge -v -H "Content-Type: application/grpc" --data-binary @- \
localhost:10000/EchoService/Echo > result.buf
The result.buf
will be in the same format as the input, which is a 1-byte compression flag (0 or 1), 4-bytes declaring the length of the protobuf data, plus the protobuf data.
You can decode it into the same format as the input with xxd
(and some awk
for the formatting). E.g.
cat result.buf | xxd -p | \
awk -v FS= -v OFS= '{for(i=1;i<NF;i++)if(i%2==1)$i="\\x"$i}1'
result:
\x00\x00\x00\x00\x04\x0a\x05\x56\x61\x6c\x75\x65
Or you could use protoc
to decode it (with dd
to strip the prefix), given the .proto
definition in ./echo.proto
:
cat result.buf | dd bs=5 skip=1 2>/dev/null | protoc --decode=EchoMessage ./echo.proto
result:
Key: "Value"
Upvotes: 9
Reputation: 2654
In order to test gRPC server without client, we have to use grpcurl
not curl
. Please take a look at https://github.com/fullstorydev/grpcurl
However, based on my experience there is a requirement to make it works. First, please ensure that your service support Reflection, you can read about it from https://github.com/sourcegraph/gophercon-2018-liveblog/issues/27. There are different ways of doing Reflection across programming languages. My advice is, just do this for the development phase, otherwise, people may querying your gRPC endpoint. Maybe you can use if()
to make a conditional block for it. For Golang, i did this
import "google.golang.org/grpc/reflection"
if os.Getenv("GO_ENV") == "development" {
reflection.Register(s)
}
then, you need to know available services in your gRPC server. There is two way you can know the structure. First You can read them from your proto file, second by executing command grpcurl localhost:10000 list
packageName.Service/rpcMethodName
. So, based on your proto, it should be something like EchoService/Echo
or if you have package name it will be packageName.EchoService/Echo
grpcurl localhost:10000 list
, just type those command and it will output service path.The last thing to note when you test it locally and you don't setup SSL/TLS, please use -plaintext
option, otherwise, it will tell you that TLS handshake failed.
Example command, based on your proto, a call in local will looks like:
grpcurl -plaintext -d '{"Key": "Value"}' 127.0.0.1:10000 EchoService/Echo
Hope it helps.
UPDATE 30 June 2020:
After a few months working with gRPC I found another interesting gRPC tool:
Upvotes: 18