gRPC with Golang
🚀 Tình huống ví dụ
Giả sử bạn đang xây một microservice UserService
với chức năng đơn giản:
GetUserById(user_id)
→ trả về thông tin user.
1️⃣ Định nghĩa file user.proto
user.proto
syntax = "proto3";
package user;
option go_package = "github.com/yourrepo/yourproject/proto/userpb";
service UserService {
rpc GetUserById(GetUserRequest) returns (GetUserResponse);
}
message GetUserRequest {
string user_id = 1;
}
message GetUserResponse {
string user_id = 1;
string name = 2;
string email = 3;
}
2️⃣ Generate code Go từ file proto
Cài đặt protoc plugin:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Chạy generate:
protoc --go_out=. --go-grpc_out=. proto/user.proto
Điều này tạo ra 2 file trong
proto/userpb
:
user.pb.go
(struct & message)
user_grpc.pb.go
(interface service)
3️⃣ Tạo Server (Go)
📁 File: server.go
server.go
package main
import (
"context"
"log"
"net"
"github.com/yourrepo/yourproject/proto/userpb"
"google.golang.org/grpc"
)
type userServer struct {
userpb.UnimplementedUserServiceServer
}
func (s *userServer) GetUserById(ctx context.Context, req *userpb.GetUserRequest) (*userpb.GetUserResponse, error) {
log.Println("Received request for user_id:", req.UserId)
// Simulate DB call
return &userpb.GetUserResponse{
UserId: req.UserId,
Name: "Tài Titans",
Email: "tai@example.com",
}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
userpb.RegisterUserServiceServer(grpcServer, &userServer{})
log.Println("gRPC server running at :50051")
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
4️⃣ Tạo Client (Go)
📁 File: client.go
client.go
package main
import (
"context"
"log"
"time"
"github.com/yourrepo/yourproject/proto/userpb"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("could not connect: %v", err)
}
defer conn.Close()
client := userpb.NewUserServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
res, err := client.GetUserById(ctx, &userpb.GetUserRequest{UserId: "123"})
if err != nil {
log.Fatalf("error calling GetUserById: %v", err)
}
log.Printf("Response: user_id=%s, name=%s, email=%s", res.UserId, res.Name, res.Email)
}
📦 Project structure gợi ý
/yourproject
├── proto/
│ └── user.proto
├── server/
│ └── server.go
├── client/
│ └── client.go
└── go.mod
✅ Tổng kết luồng hoạt động gRPC bằng Go
Thành phần
Vai trò
.proto
Định nghĩa contract, sinh code tự động
protoc
Generate interface/service
Server
Implement business logic
Client
Gọi hàm RPC như gọi local
HTTP/2
Giao thức nền tảng truyền dữ liệu
Protobuf
Dữ liệu được serialize nhanh và nhỏ gọn
📌 Gợi ý nâng cao
Dùng middleware với
grpc.UnaryInterceptor
để log, auth, trace.Dùng grpc-gateway để REST ↔ gRPC nếu bạn muốn support cả frontend.
Tạo
Makefile
hoặc bash script để build proto dễ dàng.
Last updated