Trabajar con servicios gRPC externos
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
A menudo querrás incluir en tu servidor gRPC métodos que no se generan automáticamente desde tu esquema de Ent. Para lograrlo, define los métodos en un servicio adicional dentro de un archivo .proto extra en tu directorio entpb.
Encuentra los cambios descritos en esta sección en este pull request.
Por ejemplo, supón que quieres añadir un método llamado TopUser que devuelva el usuario con el número de ID más alto. Para hacerlo, crea un nuevo archivo .proto en tu directorio entpb y define un nuevo servicio:
syntax = "proto3";
package entpb;
option go_package = "github.com/rotemtam/ent-grpc-example/ent/proto/entpb";
import "entpb/entpb.proto";
import "google/protobuf/empty.proto";
service ExtService {
rpc TopUser ( google.protobuf.Empty ) returns ( User );
}
A continuación, actualiza entpb/generate.go para incluir el nuevo archivo en la entrada del comando protoc:
- //go:generate protoc -I=.. --go_out=.. --go-grpc_out=.. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative --entgrpc_out=.. --entgrpc_opt=paths=source_relative,schema_path=../../schema entpb/entpb.proto
+ //go:generate protoc -I=.. --go_out=.. --go-grpc_out=.. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative --entgrpc_out=.. --entgrpc_opt=paths=source_relative,schema_path=../../schema entpb/entpb.proto entpb/ext.proto
A continuación, vuelve a ejecutar la generación de código:
go generate ./...
Observa que se generaron nuevos archivos en el directorio ent/proto/entpb:
tree
.
|-- entpb.pb.go
|-- entpb.proto
|-- entpb_grpc.pb.go
|-- entpb_user_service.go
|-- ext.pb.go
|-- ext.proto
|-- ext_grpc.pb.go
`-- generate.go
0 directories, 9 files
Ahora puedes implementar el método TopUser en ent/proto/entpb/ext.go:
package entpb
import (
"context"
"github.com/rotemtam/ent-grpc-example/ent"
"github.com/rotemtam/ent-grpc-example/ent/user"
"google.golang.org/protobuf/types/known/emptypb"
)
// ExtService implements ExtServiceServer.
type ExtService struct {
client *ent.Client
UnimplementedExtServiceServer
}
// TopUser returns the user with the highest ID.
func (s *ExtService) TopUser(ctx context.Context, _ *emptypb.Empty) (*User, error) {
id := s.client.User.Query().Aggregate(ent.Max(user.FieldID)).IntX(ctx)
user := s.client.User.GetX(ctx, id)
return toProtoUser(user)
}
// NewExtService returns a new ExtService.
func NewExtService(client *ent.Client) *ExtService {
return &ExtService{
client: client,
}
}
Añadir el nuevo servicio al servidor gRPC
Finalmente, actualiza cmd/server.go para incluir el nuevo servicio:
package main
import (
"context"
"log"
"net"
_ "github.com/mattn/go-sqlite3"
"github.com/rotemtam/ent-grpc-example/ent"
"github.com/rotemtam/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)
// Register the external ExtService service with the server.
entpb.RegisterExtServiceServer(server, entpb.NewExtService(client))
// 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)
}
}