Implementar streaming del lado del servidor en gRPC con Go permite enviar múltiples respuestas desde el servidor hacia el cliente a través de una única conexión. En esta guía se construyen dos métodos fundamentales: uno que recibe un stream de datos del cliente para enrolar estudiantes en un examen, y otro que responde con un stream de estudiantes inscritos en un test determinado.
¿Cómo se implementa el método enroll students con streaming del cliente?
Partiendo de la definición en protobuf, el método EnrollStudents recibe un stream de enrollment requests. A nivel de Go, la función se construye como una receiver function del test server que acepta un parámetro de tipo testpb.TestService_EnrollStudentServer [01:15]. Este parámetro representa el canal de streaming.
Dentro de la función, el flujo es el siguiente:
- Se itera llamando a
stream.Receive() para obtener cada mensaje entrante.
- Cada mensaje devuelve un
EnrollmentRequest y un posible error.
- Se verifica si el error es de tipo EOF (end of file), lo que indica que el cliente ha terminado de enviar datos [02:22].
Cuando se detecta el EOF, el servidor ejecuta SendAndClose con una respuesta que confirma la operación. Si el error es de otro tipo, se retorna directamente para señalar un fallo en la conexión.
¿Qué ocurre con cada mensaje recibido en el stream?
Por cada mensaje válido se crea un modelo de tipo models.Enrollment con el StudentID y el TestID extraídos del mensaje [03:05]. Este modelo se persiste en base de datos mediante el repositorio con SetEnrollment, pasando un contexto de background.
Un detalle importante en Go es la declaración implícita de variables. Si se escribe enrollment = ... sin los dos puntos, el compilador arroja un error indicando que la variable no ha sido declarada. La forma correcta es usar := para que Go cree y asigne la variable simultáneamente [04:00].
¿Cómo funciona el método get students per test con streaming del servidor?
Este método invierte la dirección del streaming. El cliente envía una sola petición con un TestID y el servidor responde con un stream de estudiantes [04:35]. La función recibe dos parámetros:
- Un
GetStudentsPerTestRequest con el identificador del test.
- Un
TestService_GetStudentPerTestServer, que es el stream que el servidor usa para enviar datos al cliente.
El proceso interno se compone de estos pasos:
- Se consulta la base de datos con
GetStudentPerTest pasando el TestID [05:15].
- Se itera sobre la lista de estudiantes obtenidos.
- Para cada estudiante se construye un objeto
studentpb.Student con ID, Name y Age.
- Se llama a
stream.Send() para transmitir cada estudiante al cliente [06:12].
Para evidenciar el comportamiento del streaming, se agrega un time.Sleep de dos segundos entre envíos. Esto permite observar en el cliente cómo los datos llegan de forma progresiva, no todos de golpe [06:30].
¿Cómo se prueba el streaming del servidor con Postman y Docker?
Antes de probar, es necesario reconstruir la base de datos con Docker, ya que se han añadido nuevas tablas para los enrollments [07:05].
- Se ejecuta
docker build . -t platzi-grpc-db dentro del directorio de base de datos.
- Se levanta el contenedor con
docker run -p 54321:5432 platzi-grpc-db.
- Se compilan los archivos proto tanto para test como para student.
- Se inician ambos servidores con
go run en terminales separadas [08:00].
Desde Postman, el flujo de prueba es:
- Insertar tres estudiantes (S1, S2, S3) en el servicio de student en el puerto 5060.
- Crear un test con ID T1 en el servicio de test en el puerto 5070.
- Usar
EnrollStudents para enviar tres mensajes de inscripción mediante client streaming, finalizando con end streaming [09:25].
- Invocar
GetStudentsPerTest con el test ID T1 y observar cómo los estudiantes llegan uno a uno con una pausa de dos segundos entre cada respuesta [10:10].
¿Cuál es la diferencia entre streaming de cliente y streaming de servidor?
Con el streaming del cliente, múltiples mensajes viajan desde el cliente hacia el servidor antes de recibir una única respuesta. Con el streaming del servidor, una sola petición genera múltiples respuestas que llegan de manera secuencial. Ambas técnicas se pueden combinar para lograr streaming bidireccional, donde tanto cliente como servidor envían y reciben datos simultáneamente a través del mismo canal.
¿Has implementado streaming en tus servicios gRPC? Comparte tu experiencia y las dificultades que encontraste en los comentarios.