- Understand the concept of gRPC
- RPC stands for Remote Procedure Calls
- When request to other process, make a common interface instead of communicating in JSON.
- Stub for each side is to serialize and deserialize the data
- Protocol Buffer: Serialization of data
- Define the data structure and service in .proto file
- REST uses JSON, XML, etc(no serialization)
- reference: https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
- HTTP2: Multiplexing, Header Compression, etc
- REST uses HTTP1.1
- reference:https://jumpic.com/hashtag.php?q=http2
- interface: define gRPC request and response
- server: gRPC Server
- client: gRPC Client(One time)
# Start gRPC server
./gradlew :server:bootRun
# Send a request using spring boot client
./gradlew :client:bootRun
# Send a request using grpcurl
brew install grpcurl # mac
grpcurl --plaintext -d '{"name": "grpcurl"}' localhost:19090 Simple.SayHello
- From the server log, you can check these : HTTP2, content-type: application/grpc
2024-02-09T14:36:28.596+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] INBOUND HEADERS: streamId=5 headers=GrpcHttp2RequestHeaders[:path: /Simple/SayHello, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false
- From the body, you can check the request message is serialized in binary format(protobuf)
- '{"name": "grpcurl"}' -> length=14 bytes=00000000090a076772706375726c
2024-02-09T14:36:28.597+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] INBOUND DATA: streamId=5 padding=0 endStream=true length=14 bytes=00000000090a076772706375726c
- From the response, you can check the response message is serialized in binary format(protobuf)
- '{"message":"Hello grpcurl"}' -> length=21 bytes=00000000100a0e48656c6c6f2c206772706375726c
2024-02-09T14:36:28.600+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] OUTBOUND DATA: streamId=5 padding=0 endStream=false length=21 bytes=00000000100a0e48656c6c6f2c206772706375726c
- Comparing to JSON, the binary format is more efficient in terms of size
Data | Proto buf | JSON |
---|---|---|
{"name": "grpcurl"} | 14 bytes | 23 bytes |
{"message":"Hello grpcurl"} | 21 bytes | 32 bytes |
- When using spring boot client, the stub is automatically generated by the plugin(protobuf)
- However, when using grpcurl, there is no metadata to generate the stub
- The grpcurl internally uses the reflection API to generate the stub
- From the server log, you can check the reflection API is used right before the original request
Reflection API
[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:55968] INBOUND HEADERS: streamId=3 headers=GrpcHttp2RequestHeaders[:path: /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false
And then the original API
[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:55968] INBOUND HEADERS: streamId=5 headers=GrpcHttp2RequestHeaders[:path: /Simple/SayHello, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false
- When input size is small, REST is more efficient than gRPC
- However, when input size is larget, gRPC is more efficient than REST
- reference: https://medium.com/@i.gorton/scaling-up-rest-versus-grpc-benchmark-tests-551f73ed88d4
- When data size is large, using gRPC can be a good choice.
- Plus, We can utilize the features of HTTP2 by using gRPC
- Deep Dive into gRPC(KR): https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460
- Calculate Json size: https://www.debugbear.com/json-size-analyzer
- Compare to REST: https://medium.com/@i.gorton/scaling-up-rest-versus-grpc-benchmark-tests-551f73ed88d4