Bài 3: Cài đặt công cụ và Biên dịch thủ công với protoc trong Golang
Ở hai bài học trước, chúng ta đã nắm vững cách viết cú pháp chuẩn cho các file định nghĩa .proto. Tuy nhiên, file .proto tự thân nó chỉ là một file văn bản thô (plain text). Để ứng dụng Golang của bạn có thể hiểu và sử dụng được các cấu trúc dữ liệu đó, chúng ta cần biên dịch chúng thành mã nguồn Go (.pb.go).
Trong bài học này, chúng ta sẽ thực hiện cài đặt các công cụ biên dịch cốt lõi và thực hiện biên dịch thủ công qua dòng lệnh.
1. Chuẩn bị bộ công cụ biên dịch (Toolchain)
Để biên dịch một file .proto sang mã nguồn Golang, bạn cần cài đặt 3 thành phần chính trên máy tính:
-
protoc(Protocol Compiler): Trình biên dịch gốc bằng C++ do Google phát triển, chịu trách nhiệm đọc file.protovà phân tích cú pháp. -
protoc-gen-go: Go plugin chính thức giúpprotocsinh ra các cấu trúc Struct và hàm mã hóa/giải mã (Serialization) tương thích với Go. -
protoc-gen-go-grpc: Go plugin dùng riêng để sinh ra mã nguồn giao tiếp gRPC (Client/Server stubs) nếu file.protocủa bạn có định nghĩaservice.
Hướng dẫn cài đặt nhanh:
-
Trên macOS (dùng Homebrew):
Bash
brew install protobuf go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest -
Trên Linux (Ubuntu/Debian):
Bash
sudo apt update && sudo apt install -y protobuf-compiler go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest -
Lưu ý quan trọng: Hãy đảm bảo rằng đường dẫn thư mục chứa các binary của Go (
$(go env GOPATH)/bin) đã được thêm vào biến môi trườngPATHcủa hệ điều hành, nếu khôngprotocsẽ không tìm thấy các plugin để chạy.
2. Cấu trúc thư mục dự án chuẩn
Trước khi chạy lệnh biên dịch, việc tổ chức thư mục dự án gọn gàng là điều kiện tiên quyết để mã nguồn sinh ra không bị lẫn lộn. Một dự án Go chuẩn thường có cấu trúc như sau:
Plaintext
my-grpc-project/
├── go.mod
├── proto/
│ └── user.proto <-- File định nghĩa gốc
└── pb/ <-- Thư mục chứa code Go được sinh ra tự động
Khởi tạo module Go và tải các thư viện cần thiết:
Bash
go mod init github.com/your-username/my-grpc-project
go get google.golang.org/protobuf
go get google.golang.org/grpc
3. Viết file .proto mẫu hoàn chỉnh
Tạo file proto/user.proto với nội dung tích hợp cả Message và gRPC Service để kiểm tra việc sinh code toàn diện:
Protocol Buffers
syntax = "proto3";
package user;
// Cấu hình đường dẫn sinh code trỏ thẳng vào thư mục pb bên ngoài
option go_package = "github.com/your-username/my-grpc-project/pb;pb";
message GetUserRequest {
int64 id = 1;
}
message UserResponse {
int64 id = 1;
string name = 2;
string email = 3;
}
// Định nghĩa gRPC Service để kiểm tra protoc-gen-go-grpc
service UserService {
rpc GetUser(GetUserRequest) returns (UserResponse);
}
4. Thực thi lệnh biên dịch thủ công với protoc
Mở terminal tại thư mục gốc của dự án (my-grpc-project), chạy câu lệnh protoc sau đây:
Bash
protoc \
--proto_path=proto \
--go_out=pb \
--go_opt=paths=source_relative \
--go-grpc_out=pb \
--go-grpc_opt=paths=source_relative \
proto/user.proto
Giải thích chi tiết từng tham số trong câu lệnh:
-
--proto_path=proto(hoặc-I=proto): Chỉ định cho trình biên dịch biết thư mục chứa các file.protonguồn. -
--go_out=pb: Yêu cầu sử dụng pluginprotoc-gen-gođể sinh code Go và đặt kết quả vào thư mụcpb. -
--go_opt=paths=source_relative: Giữ nguyên cấu trúc cây thư mục giống hệt như trong thư mụcprotokhi sinh ra ở thư mục đích. -
--go-grpc_out=pbvà--go-grpc_opt=paths=source_relative: Yêu cầu sinh thêm các interface gRPC Client/Server tương ứng. -
proto/user.proto: Đường dẫn của file.protocần biên dịch.
5. Kiểm tra kết quả
Sau khi chạy lệnh thành công, hãy kiểm tra thư mục pb/ của bạn. Bạn sẽ thấy hai file mới được tự động sinh ra:
-
user.pb.go: Chứa toàn bộ các Struct Go (GetUserRequest,UserResponse) và các phương thức mã hóa nhị phân (Marshal,Unmarshal). -
user_grpc.pb.go: Chứa các interface gRPC Client và Server (UserServiceClient,UserServiceServer) để bạn dễ dàng viết code network ở các bài sau.
💡 Mẹo nhỏ: Việc gõ một dòng lệnh
protocdài dòng như trên mỗi khi sửa một dấu chấm trong file.protorất dễ gây mỏi tay và sai sót. Trong thực tế, các kỹ sư sẽ gom nhóm chúng lại thành một câu lệnh tự động bằng Makefile. Đó chính là nội dung của Bài 5 sắp tới.
Bây giờ cấu trúc dữ liệu đã được biên dịch thành mã nguồn Go hoàn chỉnh. Ở bài học tiếp theo, chúng ta sẽ bắt tay vào việc viết code thực tế để hiện thực hóa gRPC Server và Client.
All rights reserved