Publicado

- 5 min read

Golang gRPC, Hola mundo!

go grpc http2
img of Golang gRPC, Hola mundo!

Hola, en está ocasión hablaremos de gRPC una de las tecnologías que esta provocando disrupción en la forma en que comunicamos nuestros microservicios, el día de hoy crearemos un hola mundo haciendo uso de esta tecnología

Introducción

gRPC(gRPC Remote Procedure Calls) o llamada de procedimiento remoto (RPC) es un framework de código abierto desarrollado inicialmente por Google, el cual incluye extensiones para balanceo de carga, rastreo, salud de nuestros servicios, comprobación y autenticación. Hace uso de Protocol Buffers para definir la estructura de nuestra aplicación. Es aplicable a aplicaciones móviles, navegadores web y servicios backend.

gRPC al día de hoy es una tecnología que se encuentra en proceso de adopción y lo que nos deja entre ver es el gran futuro que tiene esta tecnología, no es un sustituto a REST pero si una gran alternativa al momento de crear servicios que sean escalables, resilientes y de alta disponibilidad que es lo que justamente nos ofrece gRPC.

Van a ser diferentes los casos y los problemas que tengamos que resolver y tendremos que decidir qué tipo de solución podemos dar al momento de diseñar servicios ya sea usando una tecnología u otra gRPC vs APIs REST.

Algunas de las compañías que utilizan gRPC son:

  • Dropbox
  • OpenBMC
  • Netflix
  • CoreOS
  • Cisco
  • entre otros..

Nuestra app

Para nuestro ejemplo necesitamos instalar la herramienta de protocol buffer que nos permitirá construir nuestro servicio. En mi caso estoy utilizando Mac OS, para este sistema basta con ejecutar

   brew install protobuf

para el caso de versiones Linux:

   # Make sure you grab the latest version
curl -OL https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-linux-x86_64.zip
# Unzip
unzip protoc-3.5.1-linux-x86_64.zip -d protoc3
# Move protoc to /usr/local/bin/
sudo mv protoc3/bin/* /usr/local/bin/
# Move protoc3/include to /usr/local/include/
sudo mv protoc3/include/* /usr/local/include/
# Optional: change owner
sudo chown [user] /usr/local/bin/protoc
sudo chown -R [user] /usr/local/include/google

Crearemos una carpeta que llamaremos grpc-hello-world y dentro de ella inicializaremos nuestro proyecto mediante go mod init tendremos algo como esto:

   $ go mod init
go: creating new go.mod: module github.com/Josh2604/grpc-hello-world

Dentro de la carpeta ejecutaremos go get -u google.golang.org/grpc tendremos dos archivos como los siguientes:

   .
├── go.mod
└── go.sum

0 directories, 2 files

Crearemos la siguiente estructura de carpetas y archivos

   .
├── go.mod
├── go.sum
└── hello
    ├── client.go
    ├── hello.proto
    └── server.go

1 directory, 5 files

Dentro de hello.proto definiremos la estructura del request, response y la función que resolverá nuestra petición.

   syntax="proto3";

message User {
  string name=1;
  string age=2;
}

message HelloRequest {
  User user=1;
}
message HelloResponse {
  string message=1;
}
service HelloService {
  // Unary
  rpc Hello(HelloRequest) returns (HelloResponse){};
}

El ciclo de vida de RPC diferentes tipos de implementaciones en esta ocasión estaremos implementando el tipo Unary RPC, en otros posts crearemos ejemplos de las diferentes implementaciones de RPC.

Dentro de la ruta principal de nuestro proyecto crearemos el siguiente script:

   #!bin/bash
protoc hello/hello.proto --go_out=plugins=grpc:.

daremos permisos de ejecución mediante chmod u+x generate.sh y lo ejecutamos ./generate.sh esto nos generara un nuevo archivo llamado hello.pb.goque contiene lo necesario para implementar nuestro servidor y cliente con gRPC. Restructuraremos un poco el proyecto el cual quedará de la siguiente manera:

   .
├── generate.sh
├── go.mod
├── go.sum
└── hello
    ├── client
       └── client.go
    ├── hello.pb.go
    ├── hello.proto
    └── server
        └── server.go

3 directories, 7 files

Instalar dependencias en caso de que se requieran, después de la generación del archivo hello.pb.go, no tendremos que modificar nada de este archivo, contiene la implementación necesaria para nuestro ejemplo.

Ahora dentro de nuestro archivo client/client.go agregaremos lo siguiente:

   package main

import (
	"context"
	"fmt"
	"log"

	"github.com/Josh2604/grpc-hello-world/hello"
	"google.golang.org/grpc"
)

func main() {
	fmt.Println("Client running!")
	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("could not connect: %v", err)
	}
	defer conn.Close()
	c := hello.NewHelloServiceClient(conn)
	doHello(c)
}

func doHello(c hello.HelloServiceClient) {
	fmt.Println("Starting rpc")
	req := &hello.HelloRequest{
		User: &hello.User{
			Name: "test",
			Age:  "25",
		},
	}
	res, err := c.Hello(context.Background(), req)
	if err != nil {
		log.Fatalf("Error calling rpc method: %v", err)
	}

	log.Printf("Response from GreatService: %v", res.Message)
}

Y para nuestro archivo server/server.go agregamos el siguiente código:

   package main

import (
	"context"
	"fmt"
	"log"
	"net"

	"github.com/Josh2604/grpc-hello-world/hello"
	"google.golang.org/grpc"
)

type server struct{}

func (s *server) Hello(ctx context.Context, req *hello.HelloRequest) (*hello.HelloResponse, error) {
	fmt.Println("Hello Called")
	name := req.GetUser().GetName()
	age := req.GetUser().GetAge()
	result := "Hello " + name + " I'm " + age + " years old"
	res := &hello.HelloResponse{
		Message: result,
	}
	return res, nil
}

func main() {
	fmt.Println("Server running!")

	list, err := net.Listen("tcp", "0.0.0.0:50051")
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}

	// Server Creation
	s := grpc.NewServer()
	hello.RegisterHelloServiceServer(s, &server{})

	if err := s.Serve(list); err != nil {
		log.Fatalf("faile to serve: %v", err)
	}
}

Estamos listos para poder probar lo que hemos hecho hasta ahora.

Ohhh!

Abrimos nuestra terminal y dentro de la carpeta del proyecto ejecutamos los siguientes comandos

  • Servidor gor hello/server/server.go
  • Cliente gor hello/client/client.go
image-console
Ohhh!

Y Listo !! tienes tu primer hola mundo con golang y grpc. Dejo el link del repositorio, si te fue de utilidad compártelo con los demás y hagamos que la comunidad siga creciendo!!

Código

Código