برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

در دنیای میکروسرویس ها فریم ورک های RPC (Remote Procedure Call) نقش مهمی در ارتباط بین سرویس ها دارند.
یکی از فریمورکهای محبوب در این زمینه، فریم ورک gRPC است که از HTTP/2 برای انتقال داده، از پروتکل بافرها (protobufs) استفاده میکند و قابلیت هایی مثل احرازهویت، Load Balancing و موارد دیگر فراهم میکند.
در این مقاله قراره که یک CRUD (Create, Read, Update, Delete) ساده با استفاده از گولنگ و gRPC درست کنیم.
نیازمندی ها
- گولنگ
- پروتکل بافر (Protocol Buffers)
- پلاگین گولنگ برای پروتکل بافر ("protoc-gen-go" - "protoc-gen-go-grpc")
1# راه اندازی فایل پروتکل
یک فایل به نام "crud.proto" ایجاد کنید و کد زیر را داخل قرار دهید. فایل های پروتکل از .proto استفاده میکنند:
#2 تولید کد گولنگ با استفاده از فایل پروتکل
حالا ما میایم از فایل پروتکل خودمون کد های گولنگ تولید میکنیم، برای اینکار از کامند زیر استفاده میکنیم:
protoc - go_out=. - go_opt=paths=source_relative - go-grpc_out=. - go-grpc_opt=paths=source_relative crud.proto
بعد از اجرا این کامند برای شما دو فایل به نام "crud.pb.go
" و "crud_grpc.pb.go
" ایجاد میشه.
#3 پیاده سازی سرور gRPC
یک فایل به نام "server.go
" ایجاد کنید و کد زیر داخلش قرار بدید:
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
"path/to/your/project/crudpb"
)
type server struct {
crudpb.UnimplementedCRUDServiceServer
items map[string]*crudpb.Item
}
func (s *server) CreateItem(ctx context.Context, req *crudpb.CreateItemRequest) (*crudpb.CreateItemResponse, error) {
item := req.GetItem()
s.items[item.Id] = item
return &crudpb.CreateItemResponse{Item: item}, nil
}
func (s *server) ReadItem(ctx context.Context, req *crudpb.ReadItemRequest) (*crudpb.ReadItemResponse, error) {
item, exists := s.items[req.GetId()]
if !exists {
return nil, grpc.Errorf(codes.NotFound, "item not found")
}
return &crudpb.ReadItemResponse{Item: item}, nil
}
func (s *server) UpdateItem(ctx context.Context, req *crudpb.UpdateItemRequest) (*crudpb.UpdateItemResponse, error) {
item := req.GetItem()
s.items[item.Id] = item
return &crudpb.UpdateItemResponse{Item: item}, nil
}
func (s *server) DeleteItem(ctx context.Context, req *crudpb.DeleteItemRequest) (*crudpb.DeleteItemResponse, error) {
delete(s.items, req.GetId())
return &crudpb.DeleteItemResponse{Id: req.GetId()}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
crudpb.RegisterCRUDServiceServer(s, &server{items: make(map[string]*crudpb.Item)})
log.Println("Server is running on port 50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
ما نیاز داریم که به سرور gRPC وصل بشیم و با استفاده از کد بالا اینکار انجام دادیم و سرور ران کردیم.
#4 پیاده سازی gRPC Client
یک فایل به نام "client.go
" ایجاد کنید و کد زیر داخلش وارد کنید:
package main
import (
"context"
"log"
"time"
"google.golang.org/grpc"
"path/to/your/project/crudpb"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := crudpb.NewCRUDServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Create an item
item := &crudpb.Item{Id: "1", Name: "Item 1", Description: "This is item 1"}
res, err := c.CreateItem(ctx, &crudpb.CreateItemRequest{Item: item})
if err != nil {
log.Fatalf("could not create item: %v", err)
}
log.Printf("Item created: %v", res.GetItem())
// Read an item
resRead, err := c.ReadItem(ctx, &crudpb.ReadItemRequest{Id: "1"})
if err != nil {
log.Fatalf("could not read item: %v", err)
}
log.Printf("Item read: %v", resRead.GetItem())
// Update an item
item.Description = "This is the updated item 1"
resUpdate, err := c.UpdateItem(ctx, &crudpb.UpdateItemRequest{Item: item})
if err != nil {
log.Fatalf("could not update item: %v", err)
}
log.Printf("Item updated: %v", resUpdate.GetItem())
// Delete an item
resDelete, err := c.DeleteItem(ctx, &crudpb.DeleteItemRequest{Id: "1"})
if err != nil {
log.Fatalf("could not delete item: %v", err)
}
log.Printf("Item deleted: %v", resDelete.GetId())
}
#5 اجرا سرور و کلاینت
خب برای اجرا باید دستور زیر بزنید برای اجرا کردن سرور:
go run server.go
برای اجرا کردن کلاینت هم دستور زیر بزنید:
go run client.go
حالا میتونید کراد خودتون تست کنید و لذت ببرید.
شما میتونید احرازهویت و... هم به دلخواه اضافه کنید و موارد بیشتری تست بگیرید
اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁