Ответ
Разработка gRPC-сервиса на Go — это структурированный процесс, который включает следующие ключевые этапы:
1. Определение сервиса в .proto
файле
Сначала необходимо описать API сервиса с помощью Protocol Buffers. Это включает определение сервисов, их методов, а также структур сообщений (запросов и ответов).
// user_service.proto
syntax = "proto3";
package user;
option go_package = "./userpb";
// Определение сервиса
service UserService {
rpc GetUser(GetUserRequest) returns (UserResponse);
}
// Сообщение для запроса
message GetUserRequest {
string user_id = 1;
}
// Сообщение для ответа
message UserResponse {
string user_id = 1;
string name = 2;
}
2. Установка инструментов и генерация кода
Нужно установить компилятор protoc
и плагины для Go.
# Установка плагинов
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Затем сгенерировать Go-код из .proto
файла.
# Генерация кода
protoc --go_out=. --go-grpc_out=. path/to/user_service.proto
Эта команда создаст файлы *.pb.go
(со структурами сообщений) и *_grpc.pb.go
(с клиентским и серверным кодом, включая интерфейсы).
3. Реализация серверной логики
Нужно создать структуру, которая реализует сгенерированный серверный интерфейс (например, UserServiceServer
). Для обратной совместимости рекомендуется встраивать UnimplementedUserServiceServer
.
package main
import (
"context"
pb "path/to/your/gen/userpb"
)
// server реализует сгенерированный интерфейс
type server struct {
pb.UnimplementedUserServiceServer
}
// Реализация метода GetUser
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.UserResponse, error) {
// Здесь логика получения данных пользователя, например, из БД
userID := req.GetUserId()
// Пример ответа
return &pb.UserResponse{
UserId: userID,
Name: "John Doe",
}, nil
}
4. Запуск gRPC-сервера
В основной части приложения нужно создать TCP-слушатель, инстанцировать gRPC-сервер, зарегистрировать на нем свою реализацию сервиса и запустить его.
package main
import (
"log"
"net"
pb "path/to/your/gen/userpb"
"google.golang.org/grpc"
)
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// Создаем новый gRPC сервер
grpcServer := grpc.NewServer()
// Регистрируем нашу реализацию сервиса
pb.RegisterUserServiceServer(grpcServer, &server{})
log.Println("gRPC server listening at :50051")
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}