Creating the Server and Client
We decided not to generate this part automatically because it typically involves some team/org specific behavior such as wiring in different middlewares. This may change in the future. In the meantime, this section describes how to create a simple gRPC server that will serve our service code.
Create a new file and write:
go get -u github.com/mattn/go-sqlite3
Next, let’s run the server, while we write a client that will communicate with it:
Creating the Client
Let’s create a simple client that makes some calls to our server. Create a new file named cmd/client/main.go
and write:
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())
conn, err := grpc.Dial(":5000", grpc.WithInsecure())
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()),
}
}
Observe the output:
Hooray! We have successfully created a real gRPC client to talk to our real gRPC server! In the next sections, we will see how the ent/gRPC integration deals with more advanced ent schema definitions.