gRPC-Web com Golang e VueJS: Uma alternativa ao REST e GraphQL
gRPC-Web é uma biblioteca JavaScript que permite a comunicação direta entre front-end e back-end sem precisar de um servidor HTTP intermediário.
Com o gRPC-Web, você pode facilmenete criar um aplicação com arquiterura gRPC de ponta-a-ponta ao definir os tipos de dados e seriços com Protocol Buffers.
gRPC é um sistema de chamada de procedimento remoto (RPC - Remoce Procedure Call) rápido e eficiente que permite que microserviços se comuniquem. Você pode aprender mais sobre gRPC na documentação oficial ou em outro artigo que eu escrevi com o título Building microservices in Go and Python using gRPC.
gRPC-Web, tal como gRPC, permite que seja definido um “contrato” de serviço entre o cliente e o servidor usando a estrutura protobuf. Você cria a definição dos tipos de dados, o nome dos serviços e os valores que eles recebem e retornam, utilizando Protocol Buffers, e depois utiliza o compilador protoc para gerar o código necessário para a comunicação entre front-end e back-end. Esse processo de desenvolvimento evita a necessidade de ter que lidar com coisas como lógica de serialização e deserialização de JSON, status code do HTTP, content-types, headers etc.
Vantanges de usar gRPC-Web
- gRPC de ponta-a-ponta: O cliente pode interagir diretamente com um ou mais servidores gRPC apenas chamando as funções definidas.
- Proximidade entre equipes de front-end e back-end: Utilizando Protocol Buffers para definir todos os serviços, a interação entre front e back é apenas mais uma camada gRPC. O contrato entre front e back é conhecido e o código do cliente pode ser regerado quando houver alguma mudança no contrato.
- Facilidade para gerar bibliotecas de cliente: Não precisa importar bibliotecas de terceiros como axios. O código gerado pelo compilador protoc pode ser importado para qualquer cliente.
Exemplo de uma aplicação gRPC-Web
Eu comecei criando o arquivo de definição accounts.proto simples como esse:
syntax = "proto3";
package private;
option go_package = "proto";
service AccountService {
rpc Create(User) returns (User) {}
rpc AuthenticateByEmailAndPassword(User) returns (Account) {}
}
message User {
string email = 1;
string password = 2;
}
message Account {
string token = 1;
}
message Nothing {}
Então eu executei os comandos abaixo para gerar os códigos do servidor e do cliente:
protoc -I proto proto/*.proto --proto_path=./proto --go_out=plugins=grpc:./backend/proto
protoc -I proto proto/*.proto --js_out=import_style=commonjs:./frontend/proto --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./frontend/proto
O comando acima cria o arquivo frontend/proto/accounts_grpc_web_pb.js contendo a implementação dos serviços e o arquivo frontend/proto/accounts_pb.js contendo a definição dos tipos de dados.
Depois disso, eu implementei um código em Go e a chamada ao serviço em Javascript. Abaixo um exemplo mais ou menos do código que está no GitHub:
import (
...
pb "backend/proto"
)
func (instance *AccountServer) Create(ctx context.Context, req *pb.User) (*pb.User, error) {
user := structs.User{
Email: req.Email,
Password: req.Password,
}
query := `INSERT INTO accounts (email, password) VALUES (:email, :password);`
conn := instance.db.GetConnection()
_, err := conn.NamedExec(query, &user)
return &pb.User{Email: user.Email}, err
}
E chamei a função gRPC create no Javascript:
import { Account, User } from '../../proto/accounts_pb'
import { AccountServicePromiseClient } from '../../proto/accounts_grpc_web_pb'
export default class {
constructor () {
this.client = new AccountServicePromiseClient('http://localhost:9000', null, null)
}
async create (user) {
const req = new User()
req.setEmail('me@gustavohenrique.com')
req.setPassword('verystrongpassword')
try {
const res = await this.client.create(req, {})
return res.getEmail()
} catch (err) {
console.error(err.message)
throw err
}
}
}
O código completo escrito em Golang e VueJS (usando Quasar Framework) pode ser encontrado nesse repositório.
Conclusão
Agora você deve estar se perguntando “Eu devo utilizar gRPC?”
gRPC é arquitetura robusta que possui vários apoiadores. Empresas como Google, Netflix e Dropbox já utilizam em produção. Por ter uma baixa curva de aprendizado, novos desenvolvedores em um projeto gRPC conseguem ser produtivos rapidamente. A definição dos tipos e serviços em Protocol Buffer funciona como uma documentação também - quem for consumir o serviço consegue saber o que deve enviar no request e o que pode ser recebido no response.
gRPC-Web é uma excelente opção para desenvolvedores da web. Ele traz portabilidade, excelente performance e um protocolo sofisticado para uso no front-end web ou mobile.