ساخت یک CRUD با گولنگ و gRPC

در دنیای میکروسرویس ها فریم ورک های 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

حالا میتونید کراد خودتون تست کنید و لذت ببرید.


شما میتونید احرازهویت و... هم به دلخواه اضافه کنید و موارد بیشتری تست بگیرید

1 🔥
1 🎉
1 😮
1 👍
1 💜
2 👏
میلاد خسروی
نویسنده کد نیوز

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

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁