0

Bài 5: Tự động hóa quá trình Build Protobuf với Makefile

Ở Bài 3, chúng ta đã làm quen với câu lệnh protoc thủ công. Bạn có nhận ra rằng lệnh đó cực kỳ dài dòng, dễ gây sai sót cú pháp, và mỗi khi thêm một file .proto mới, bạn lại phải copy-paste lại cả một đoạn dài ngút ngàn không?

Trong môi trường làm việc thực tế, việc này phải được tự động hóa hoàn toàn. Bất kỳ lập trình viên nào trong team cũng chỉ nên gõ một câu lệnh duy nhất là mọi thứ tự động được biên dịch sạch sẽ.

Trong bài học này, chúng ta sẽ học cách sử dụng Makefile để tự động hóa toàn bộ quy trình build Protobuf.

1. Makefile là gì và tại sao Backend Engineer cần nó?

Makefile là một file cấu hình tập lệnh (scripting) được thực thi bởi công cụ make (có sẵn trên hầu hết các hệ điều hành Unix/Linux/macOS).

Nó giúp bạn gom nhóm các chuỗi lệnh phức tạp, dài dòng thành các tác vụ (targets) ngắn gọn. Thay vì phải nhớ và gõ một đống tham số protoc phức tạp, giờ đây bạn chỉ cần gõ make proto. Điều này đặc biệt hữu ích khi tích hợp vào các pipeline CI/CD (GitHub Actions, GitLab CI).

2. Thiết kế Cấu trúc Makefile cho Protobuf

Tạo một file mang tên chính xác là Makefile (không có phần mở rộng) nằm ngay tại thư mục gốc của dự án (my-grpc-project/):

Plaintext

my-grpc-project/
├── Makefile  <-- File Makefile đặt ở đây
├── go.mod
├── proto/
│   └── user.proto
└── pb/

Dưới đây là mã nguồn chuẩn của một Makefile tối ưu dành cho việc biên dịch Protobuf:

Makefile

# Định nghĩa các biến đường dẫn thư mục
PROTO_DIR = proto
OUT_DIR = pb

# Khai báo các lệnh giả (phony targets) để tránh xung đột với tên file thật nếu có
.PHONY: proto clean help

# Lệnh mặc định khi bạn chỉ gõ 'make'
help:
	@echo "Vui lòng chọn lệnh hỗ trợ:"
	@echo "  make proto  - Biên dịch toàn bộ các file .proto sang mã nguồn Go"
	@echo "  make clean  - Xóa sạch các file code cũ trong thư mục pb"

# Lệnh biên dịch chính
proto:
	@echo "==> Đang kiểm tra và tạo thư mục đích ($(OUT_DIR))..."
	@mkdir -p $(OUT_DIR)
	@echo "==> Đang biên dịch các file .proto..."
	protoc \
		--proto_path=$(PROTO_DIR) \
		--go_out=$(OUT_DIR) \
		--go_opt=paths=source_relative \
		--go-grpc_out=$(OUT_DIR) \
		--go-grpc_opt=paths=source_relative \
		$(PROTO_DIR)/*.proto
	@echo "==> Biên dịch Protobuf hoàn tất thành công!"

# Lệnh dọn dẹp mã nguồn cũ
clean:
	@echo "==> Đang dọn dẹp thư mục $(OUT_DIR)..."
	@rm -rf $(OUT_DIR)/*
	@echo "==> Dọn dẹp hoàn tất!"

3. Giải thích chi tiết các thành phần trong Makefile

  1. PROTO_DIR và OUT_DIR: Biến tùy chỉnh giúp bạn dễ dàng thay đổi tên thư mục nguồn hoặc thư mục đích ở một nơi duy nhất mà không phải sửa lại toàn bộ lệnh bên dưới.

  2. .PHONY: proto clean help: Giúp hệ thống hiểu rằng proto, clean, help là các nhãn tác vụ hành động chứ không phải là tên file vật lý trên đĩa cứng.

  3. @mkdir -p $(OUT_DIR): Dấu @ ở đầu dòng giúp ẩn câu lệnh gốc khi chạy, chỉ in ra màn hình thông báo sạch sẽ. Tham số -p giúp tự động tạo thư mục nếu nó chưa tồn tại mà không báo lỗi nếu nó đã có sẵn.

  4. $(PROTO_DIR)/*.proto: Tự động tìm và biên dịch tất cả các file có đuôi .proto nằm trong thư mục proto/, giúp bạn không phải khai báo thủ công từng file một khi dự án phình to ra hàng chục file service.

4. Trải nghiệm sức mạnh tự động hóa

Bây giờ, bất cứ khi nào bạn thay đổi cấu trúc dữ liệu trong file .proto, bạn không cần phải gõ lệnh protoc dài dòng nữa. Bạn chỉ cần mở terminal và thực hiện:

  • Dọn dẹp code cũ (nếu muốn làm sạch):

    Bash

    make clean
    
    
  • Biên dịch nhanh chóng:

    Bash

    make proto
    
    

Chỉ trong một tích tắc, toàn bộ file mã nguồn .pb.go và _grpc.pb.go được tự động sinh ra chuẩn xác trong thư mục pb/. Quá trình này hoàn toàn mượt mà và chuẩn hóa cho mọi thành viên trong team.

Tổng kết

Makefile là một công cụ kinh điển giúp tự động hóa quy trình phát triển phần mềm, biến những câu lệnh biên dịch phức tạp thành một thao tác make proto đơn giản.

Tuy nhiên, khi dự án Microservices mở rộng lên quy mô lớn (hàng chục team cùng đóng góp vào các file .proto chung), việc quản lý bằng protoc truyền thống bắt đầu phát sinh thêm các bài toán khó: làm sao để kiểm tra lỗi cú pháp chuẩn hóa (Linting), và làm sao để phát hiện xung đột thay đổi ngầm (Breaking-change detection)?

Đó chính là nội dung của bài học cuối cùng trong series: Quản lý Proto Repository chuyên nghiệp với công cụ Buf.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí