Implementación de gRPC Server y Métodos en Go

Clase 13 de 22Curso de Go Avanzado: Protobuffers y gRPC

Resumen

¿Cómo implementar un nuevo servicio en el servidor gRPC?

En el emocionante mundo del desarrollo de servicios con gRPC, dar vida a un nuevo servidor puede parecer un desafío, pero con una guía clara, estarás en camino de crear servicios robustos y eficientes. Aquí exploramos cómo implementar un nuevo servicio, el servidor gRPC, paso a paso, desde la estructura de la base de datos hasta la implementación final en Go.

¿Cómo se define la nueva tabla en la base de datos?

Para iniciar, se debe crear una nueva tabla en SQL. Esta tabla se denominará test y se compondrá de un ID tipo Varchar que actuará como llave primaria y un nombre que no puede ser nulo. Antes de construirla, es esencial asegurarse de eliminar cualquier existencia previa de la tabla para evitar conflictos.

DROP TABLE IF EXISTS test;
CREATE TABLE test (
  ID VARCHAR PRIMARY KEY,
  nombre VARCHAR NOT NULL
); 

¿Cómo se estructuran los modelos en Go?

En Go, los modelos se definen usando structs. Un nuevo struct llamado Test se creará con los campos ID y nombre, ambos de tipo string.

type Test struct {
    ID    string
    Nombre string
}

¿Cómo se modifica el repositorio para soportar el nuevo modelo?

Se deben agregar métodos al repositorio para manejar las operaciones del nuevo modelo:

  1. getTest: recibe un contexto y un ID, y devuelve un modelo Test y un error.
  2. setTest: recibe un contexto y un Test, y devuelve un error.

Estos métodos deben implementarse tanto a nivel abstracto como en la especificidad del repositorio, por ejemplo, en PostgreSQL.

func (r *Repo) GetTest(ctx context.Context, id string) (*models.Test, error) {
    // implementación
}

func (r *Repo) SetTest(ctx context.Context, test *models.Test) error {
    // implementación
}

¿Cómo crear el nuevo servidor gRPC?

En el directorio server, se crea un nuevo archivo test.go para manejar el nuevo servicio. Aquí se define el TestServer usando composición sobre herencia para implementar el UnimplementedTestServiceServer del archivo testpb.

type TestServer struct {
    repo Repository
    testpb.UnimplementedTestServiceServer
}

func NewTestServer(repo Repository) *TestServer {
    return &TestServer{repo: repo}
}

¿Qué funciones manejarán las solicitudes gRPC?

Es fundamental implementar las funciones getTest y setTest para el servidor.

func (s *TestServer) GetTest(ctx context.Context, req *testpb.GetTestRequest) (*testpb.Test, error) {
    test, err := s.repo.GetTest(ctx, req.GetId())
    if err != nil {
        return nil, err
    }
    return &testpb.Test{Id: test.ID, Name: test.Nombre}, nil
}

func (s *TestServer) SetTest(ctx context.Context, req *testpb.SetTestRequest) (*testpb.SetTestResponse, error) {
    test := &models.Test{ID: req.GetTest().GetId(), Nombre: req.GetTest().GetName()}
    err := s.repo.SetTest(ctx, test)
    if err != nil {
        return nil, err
    }
    return &testpb.SetTestResponse{Id: test.ID, Name: test.Nombre}, nil
}

¿Cómo conectar el nuevo servidor al gRPC?

La etapa final consiste en registrar tu nuevo servidor con gRPC. En un nuevo directorio server_test, crea el main.go que instanciará el servidor en un puerto único. Activa la reflexión para facilitar la interacción con herramientas como Postman.

func main() {
    server := grpc.NewServer()
    repo := // crear e inicializar repositorio
    testpb.RegisterTestServiceServer(server, NewTestServer(repo))
    // otros detalles de inicialización
}

¿Cómo se ejecuta y prueba el nuevo servidor?

Una vez compilados los cambios, inicia el nuevo servidor y verificar con Postman o cualquier cliente gRPC configurado para interactuar con él. Realiza pruebas para los métodos setTest y getTest, asegurando que la interacción y la gestión de datos sean fluidas y efectivas.

Con todo esto implementado, no solo has añadido un nuevo servicio a tu servidor gRPC, sino que has incrementado la robustez y flexibilidad de tu aplicación. Prepárate, porque el mundo del streaming de gRPC es el próximo paso hacia un desarrollo aún más innovador.