What is RPC? RPC means “remote procedure call”. The concept is called a remote function as a local function.
Then gRPC? It is a framework that helps you create RPC.
Traditional RPC has some problem making it hard to use. For example, how do you know, what type of message you get?
Usually, we use JSON or others format. But marshal & unmarshal quickly became a big issue. Because as time goes on, we don’t actually know which service use which field, thus we can’t reduce anything.
And server & client will get further farther for the same reason.
These all, won’t be an issue in gRPC.
In gRPC, you define a*.proto
file for your service.
At here, we will create one namedUserService
syntax="proto3";packageuser;serviceUserService{rpcGetUser(Empty)returns(User){}}// define message typemessageEmpty{}messageUser{stringname=1;int32age=2;}
To generate code, I usually usego generate ./...
So let’s have a filegen.go
, just leave a comment about what command you want to execute.
//go:generate sh -c "protoc -I./user --go_out=plugins=grpc:./user ./user/*.proto"
Implement service:
import"path/to/grpc_generated/user"typeUserServicestruct{}func(us*UserService)GetUser(ctxcontext.Context,u*user.Empty)(*user.User,error){return&user.UserName{Name:"Danny",Age:21,},nil}
Create server:
import("net""path/to/grpc_generated/user""google.golang.org/grpc")funcmain(){l,err:=net.Listen("tcp",":50051")// handle errserver:=grpc.NewServer()service:=user.UserServiceServer(&UserService{})user.RegisterUserServiceServer(server,service)err=server.Serve(l)// handle err}
Final is our client:
import("fmt""net""path/to/grpc_generated/user""google.golang.org/grpc")funcmain(){conn,err:=grpc.Dial("localhost:50051",grpc.WithInsercure())// handle errdeferconn.Close()client:=user.NewUserServiceClient(conn)u,err:=client.GetUser(context.Background(),&user.Empty{})// handle errfmt.Printf("Name: %s, Age: %d",u.Name,u.Age)}
After that, rungo generate ./...
from project root dir.
Thengo run server.go
, open another terminal,go run client.go
I usually won’t commit generated code(unless commit it makes sense), so I usually will write*.pb.go
in file.gitignore
More info:
Top comments(7)

- LocationKuala Lumpur, Malaysia
- Joined
What's interesting to me is that when I create the GRPC client in another package (outside main) and try to use it elsewhere... the GRPC calls fails with:
rpc error: code = Canceled desc = grpc: the client connection is closing
Any thoughts on this peculiarity?

- Email
- LocationTaiwan
- EducationKaohsiung Medical University
- Joined
Not sure what happened on your computer, could you provide a sample for reproducing?

- LocationKuala Lumpur, Malaysia
- Joined
Thanks for the reply. I figured it out. Gotta be careful withdefer conn.Close()
if calling outside main function... After function ends it will close the connection and the client cannot be used anymore.

- Email
- LocationTaiwan
- EducationKaohsiung Medical University
- Joined
Good to hear that; yes, better to using context if you want to manage the lifecycle. It provides a not bad abstraction for stopping a goroutine.

- LocationSurabaya, Indonesia
- EducationEEPIS
- Joined
Hey, i already have golang backend with rest api implemented. can i use grpc without make .proto file ? because i already have service, interface, repo, etc

- Email
- LocationTaiwan
- EducationKaohsiung Medical University
- Joined
A short answer is it's possible, but that also means you are using HTTP2 directly.
That would make the gRPC became useless. Or you have to implement client/server-side abstraction for RPC.
Therefore I guess you probably can use .proto, just redirect to existed services.

- LocationSurabaya, Indonesia
- EducationEEPIS
- Joined
maybe last option helpful for me. okay i will try it. thanks for suggest me :)
For further actions, you may consider blocking this person and/orreporting abuse