Saltar al contenido principal

Creación del Servidor y Cliente

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Obtener una definición de servicio gRPC generada automáticamente es genial, pero aún necesitamos registrarla en un servidor gRPC concreto que escuche en algún puerto TCP para recibir tráfico y pueda responder a llamadas RPC.

Decidimos no generar esta parte automáticamente porque normalmente involucra comportamientos específicos de equipos/organizaciones, como la integración de diferentes middlewares. Esto podría cambiar en el futuro. Mientras tanto, esta sección describe cómo crear un servidor gRPC sencillo que sirva nuestro código de servicio.

Creación del servidor

Crea un nuevo archivo cmd/server/main.go y escribe:

package main

import (
"context"
"log"
"net"

_ "github.com/mattn/go-sqlite3"
"ent-grpc-example/ent"
"ent-grpc-example/ent/proto/entpb"
"google.golang.org/grpc"
)

func main() {
// Initialize an ent client.
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("failed opening connection to sqlite: %v", err)
}
defer client.Close()

// Run the migration tool (creating tables, etc).
if err := client.Schema.Create(context.Background()); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}

// Initialize the generated User service.
svc := entpb.NewUserService(client)

// Create a new gRPC server (you can wire multiple services to a single server).
server := grpc.NewServer()

// Register the User service with the server.
entpb.RegisterUserServiceServer(server, svc)

// Open port 5000 for listening to traffic.
lis, err := net.Listen("tcp", ":5000")
if err != nil {
log.Fatalf("failed listening: %s", err)
}

// Listen for traffic indefinitely.
if err := server.Serve(lis); err != nil {
log.Fatalf("server ended: %s", err)
}
}

Fíjate que hemos añadido una importación de github.com/mattn/go-sqlite3, por lo que debemos añadirla a nuestro módulo:

go get -u github.com/mattn/go-sqlite3

A continuación, vamos a ejecutar el servidor mientras escribimos un cliente que se comunicará con él:

go run -mod=mod ./cmd/server

Creación del cliente

Creemos un cliente sencillo que realice algunas llamadas a nuestro servidor. Crea un nuevo archivo llamado cmd/client/main.go y escribe:

package main

import (
"context"
"fmt"
"log"
"math/rand"
"time"

"ent-grpc-example/ent/proto/entpb"
"google.golang.org/grpc"
"google.golang.org/grpc/status"
)

func main() {
rand.Seed(time.Now().UnixNano())

// Open a connection to the server.
conn, err := grpc.Dial(":5000", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("failed connecting to server: %s", err)
}
defer conn.Close()

// Create a User service Client on the connection.
client := entpb.NewUserServiceClient(conn)

// Ask the server to create a random User.
ctx := context.Background()
user := randomUser()
created, err := client.Create(ctx, &entpb.CreateUserRequest{
User: user,
})
if err != nil {
se, _ := status.FromError(err)
log.Fatalf("failed creating user: status=%s message=%s", se.Code(), se.Message())
}
log.Printf("user created with id: %d", created.Id)

// On a separate RPC invocation, retrieve the user we saved previously.
get, err := client.Get(ctx, &entpb.GetUserRequest{
Id: created.Id,
})
if err != nil {
se, _ := status.FromError(err)
log.Fatalf("failed retrieving user: status=%s message=%s", se.Code(), se.Message())
}
log.Printf("retrieved user with id=%d: %v", get.Id, get)
}

func randomUser() *entpb.User {
return &entpb.User{
Name: fmt.Sprintf("user_%d", rand.Int()),
EmailAddress: fmt.Sprintf("user_%d@example.com", rand.Int()),
}
}

Nuestro cliente crea una conexión al puerto 5000, donde está escuchando nuestro servidor, luego realiza una solicitud Create para crear un nuevo usuario, y posteriormente una segunda solicitud Get para recuperarlo de la base de datos. Ejecutemos nuestro código de cliente:

go run ./cmd/client

Ejecutemos nuestro código de cliente:

2021/03/18 10:42:58 user created with id: 1
2021/03/18 10:42:58 retrieved user with id=1: id:1 name:"user_730811260095307266" email_address:"user_7338662242574055998@example.com"

¡Hurra! ¡Hemos creado con éxito un cliente gRPC real que se comunica con nuestro servidor gRPC real! En las próximas secciones, veremos cómo la integración ent/gRPC maneja definiciones de esquema ent más avanzadas.