Примеры организации grpc кода в go?

В Go существует несколько способов организации кода для работы с gRPC.

Прежде чем начать, давайте вспомним, что gRPC - это средство обмена данными и создания межсервисных взаимодействий с использованием протокола Remote Procedure Call (RPC). Go предоставляет нативную поддержку для gRPC с помощью богатого набора инструментов и пакетов из стандартной библиотеки, таких как net, http и google.golang.org/grpc.

Одна из распространенных организаций кода в Go - это использование пакетов. Вы можете разделить свой код на несколько пакетов, каждый из которых будет отвечать за отдельную функциональность.

Это может выглядеть следующим образом:

- В корневом каталоге вашего проекта создайте пакет api, который будет содержать определения ваших gRPC-сервисов.
- В пакете api создайте файл service.proto, в котором определите свои gRPC-сервисы и сообщения с использованием языка описания интерфейсов Protocol Buffers (protobuf). Пример:

syntax = "proto3";

package api;

service MyService {
    rpc MyMethod(Request) returns (Response);
}

message Request {
    string name = 1;
}

message Response {
    string message = 1;
}

- Используйте команду protoc (входящую в состав инструментов gRPC) для генерации кода на основе service.proto. Создайте каталог api/generated, а затем запустите команду:

protoc --go_out=plugins=grpc:api/generated service.proto

- В каталоге api/generated появятся сгенерированные файлы service.pb.go и service_grpc.pb.go, которые будут содержать код для работы с gRPC в Go.

- Создайте дополнительный пакет server для реализации логики вашего сервера gRPC. Файл server.go будет использовать сгенерированные файлы service.pb.go и service_grpc.pb.go в своей работе. Пример:

package server

import (
    "context"
    "log"

    "path/to/api"
    "google.golang.org/grpc"
)

type myServiceServer struct{}

func (s *myServiceServer) MyMethod(ctx context.Context, req *api.Request) (*api.Response, error) {
    log.Println("Received request with name: ", req.Name)

    // Ваша бизнес-логика
    message := "Hello, " + req.Name

    return &api.Response{Message: message}, nil
}

func StartServer() {
    grpcServer := grpc.NewServer()

    api.RegisterMyServiceServer(grpcServer, &myServiceServer{})

    // Запустите сервер на адресе и порту вашего выбора
    // Например, "localhost:50051"
    grpcServer.Serve(lis)
}

- Дополнительно вы можете создать пакет client для реализации клиента gRPC. Файл client.go будет использовать сгенерированные файлы service.pb.go и service_grpc.pb.go для взаимодействия с сервером gRPC. Пример:

package client

import (
    "context"
    "log"

    "path/to/api"
    "google.golang.org/grpc"
)

func CallMyMethod() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer conn.Close()

    client := api.NewMyServiceClient(conn)

    req := &api.Request{Name: "John"}
    res, err := client.MyMethod(context.Background(), req)
    if err != nil {
        log.Fatalf("Request failed: %v", err)
    }

    log.Println("Response: ", res.Message)
}

Это основная структура организации кода для работы с gRPC в Go. Разделение кода на пакеты позволяет получить хорошую модульность и четкое разделение обязанностей.