gRPC Hola mundo con golang
Tags: go, grpc, http2
Published: 2021-05-22 02:19:24

> _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](https://developers.google.com/protocol-buffers/docs/overview) 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](https://es.sensedia.com/post/apis-rest-graphql-or-grpc-who-wins-this-game).

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 
```sh
brew install protobuf
```
para el caso de versiones Linux:
```sh
# 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:
```sh
$ 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:
```sh
.
├── go.mod
└── go.sum

0 directories, 2 files
```
Crearemos la siguiente estructura de carpetas y archivos
```sh
.
├── 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.
```proto
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](https://grpc.io/docs/what-is-grpc/core-concepts/).

Dentro de la ruta principal de nuestro proyecto crearemos el siguiente script:
```sh
#!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.go`que contiene lo necesario para implementar nuestro servidor y cliente con gRPC. Restructuraremos un poco el proyecto el cual quedará de la siguiente manera:
```sh
.
├── 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:
```go
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:

```go
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.
![ok](https://media.giphy.com/media/3oEjI5VtIhHvK37WYo/giphy.gif)

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`

![Captura de Pantalla 2021-05-21 a la(s) 20.47.00](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfpl3yssgiwi2vz97pyo.png)
 
![Ohhh!](https://media.giphy.com/media/NEvPzZ8bd1V4Y/giphy.gif)

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!!

Puedes ver mas publicaciones visitando mi sitio web [literalcoder.com](https://literalcoder.com) :)

{% github Josh2604/grpc-hello-world no-readme %}