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:

    1. 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:

    1. package main
    2. import (
    3. "context"
    4. "fmt"
    5. "log"
    6. "math/rand"
    7. "time"
    8. "ent-grpc-example/ent/proto/entpb"
    9. "google.golang.org/grpc"
    10. "google.golang.org/grpc/status"
    11. )
    12. func main() {
    13. rand.Seed(time.Now().UnixNano())
    14. conn, err := grpc.Dial(":5000", grpc.WithInsecure())
    15. if err != nil {
    16. log.Fatalf("failed connecting to server: %s", err)
    17. }
    18. defer conn.Close()
    19. // Create a User service Client on the connection.
    20. client := entpb.NewUserServiceClient(conn)
    21. // Ask the server to create a random User.
    22. ctx := context.Background()
    23. user := randomUser()
    24. created, err := client.Create(ctx, &entpb.CreateUserRequest{
    25. User: user,
    26. })
    27. if err != nil {
    28. se, _ := status.FromError(err)
    29. log.Fatalf("failed creating user: status=%s message=%s", se.Code(), se.Message())
    30. log.Printf("user created with id: %d", created.Id)
    31. // On a separate RPC invocation, retrieve the user we saved previously.
    32. get, err := client.Get(ctx, &entpb.GetUserRequest{
    33. Id: created.Id,
    34. })
    35. if err != nil {
    36. se, _ := status.FromError(err)
    37. log.Fatalf("failed retrieving user: status=%s message=%s", se.Code(), se.Message())
    38. }
    39. log.Printf("retrieved user with id=%d: %v", get.Id, get)
    40. }
    41. func randomUser() *entpb.User {
    42. return &entpb.User{
    43. Name: fmt.Sprintf("user_%d", rand.Int()),
    44. EmailAddress: fmt.Sprintf("user_%d@example.com", rand.Int()),
    45. }
    46. }

    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.