Skip to content

Commit

Permalink
Merge pull request #1012 from eleven-labs/feat/codelabs-microservice-…
Browse files Browse the repository at this point in the history
…avec-go-et-grpc

Migrate microservice avec go et grpc (codelabs)
  • Loading branch information
fpasquet authored Oct 31, 2023
2 parents 724dc9a + 518aee6 commit fd89f84
Show file tree
Hide file tree
Showing 8 changed files with 589 additions and 0 deletions.
24 changes: 24 additions & 0 deletions _tutorials/fr/2018-05-15-microservice-avec-go-et-grpc/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
contentType: tutorial
lang: fr
date: '2018-05-15'
slug: microservice-avec-go-et-grpc
title: Microservice avec Go et gRPC
excerpt: >-
Dans ce tutoriel nous allons mettre en place un microservice gRPC de traduction avec Google Translate.
cover: /assets/2018-03-28-graphql-avec-symfony/cover.jpg
categories:
- architecture
authors:
- qneyrat
keywords:
- microservices
steps:
- introduction
- installation-des-outils
- declaration-du-protobuf
- mise-en-place-de-la-translate-api-de-google
- mise-en-place-du-client-grpc
- ajout-proxy-rest-et-doc-swagger
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
contentType: tutorial-step
tutorial: microservice-avec-go-et-grpc
slug: ajout-proxy-rest-et-doc-swagger
title: Ajout d'un proxy REST et d'une doc Swagger
---
Nous allons maintenant voir comment exposer un service gPRC comme une API REST.
Puisqu'un serveur gRPC n'est pas disponible pour le web, l'une des solutions est de créer un autre service qui va exposer une route REST et appeler le service gRPC.

[grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) est un plugin protoc pour auto-générer un proxy HTTP via de la conf dans le fichier protobuf.
```
HTTP request
|
v
-------------- ---------------
| HTTP Proxy | json/proto | gRPC Server |
| on :8001 | -------------> | on :4000 |
-------------- <------------- ---------------
```
Nous allons commencer par installer les plugins `grpc-gateway` et `swagger` pour protoc.
```bash
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
```

Nous allons modifier le fichier `proto/translator.proto` pour ajouter les directives de génération du proxy HTTP.
Pour ce faire, il faut ajouter des options à notre endpoint RPC.
```proto
option (google.api.http) = {
post: "/v1/translate"
body: "*"
};
```
Ici, on définit une route `/v1/translate` avec le verbe POST.

Ce qui nous donne :
```proto
syntax = "proto3";
package proto;
import "google/api/annotations.proto";
enum Language {
en = 0;
fr = 1;
}
message TranslateRequest {
string text = 1;
Language language = 2;
}
message TranslateResponse {
string text = 1;
}
service Translator {
rpc Translate(TranslateRequest) returns (TranslateResponse) {
option (google.api.http) = {
post: "/v1/translate"
body: "*"
};
}
}
```

Nous allons maintenant modifer le fichier `prototool.yaml` pour générer le proxy et le json de Swagger.
```yaml
# prototool.yaml
protoc_includes:
- ../../src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis

gen:
go_options: import_path: translator-service/

plugins:
- name: go
type: go
flags: plugins=grpc
output: .
- name: grpc-gateway
type: go
output: .
- name: swagger
type: go
output: swagger/.
```
Nous pouvons maintenant générer les fichiers Go.
```bash
prototool gen
```
Nous allons maintenant utiliser ce proxy qui a été généré et créer un fichier `proxy.go`.
Il suffit de lancer le serveur gRPC dans une goroutine et d'exposer le proxy HTTP.
```go
// proxy.go
package main

import (
"context"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
"translator-service/proto"
)

func main() {
lis, err := net.Listen("tcp", "localhost:4000")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
translator := translate.NewGoogleTranslator(os.Getenv("TRANSLATION_API_KEY"))
srv := server.NewTranslatorServer(server.Endpoints{
TranslateEndpoint: server.NewTranslateEndpoint(translator),
})
s := grpc.NewServer()
proto.RegisterTranslatorServer(s, srv)
go s.Serve(lis)

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
proto.RegisterTranslatorHandlerFromEndpoint(ctx, mux, "localhost:4000", opts)

http.ListenAndServe(":8001", mux)
}
```
Nous pouvons maintenant compiler notre serveur.
```bash
TRANSLATION_API_KEY=yourapitoken go run main.go
```

Et vérifier que cela fonctionne bien :
```bash
curl -X POST http://localhost:8001/v1/translate \ [±master ✓]
-H 'Content-Type: application/json' \
-d '{
"text": "Salut les astronautes !",
"language": "en"
}'
```

On peut remarquer qu'un fichier json a été aussi généré dans le dossier `swagger/proto`.
Il s'agit de la documentation Swagger qui a été générée à partir des directives présentes dans le fichier protobuf.

Vous pouvez ouvrir la documentation [directement ici](https://editor.swagger.io/) ou directement utiliser [swagger-ui](https://github.com/swagger-api/swagger-ui).

### Conclusion

Nous avons maintenant un service documenté accessible via gRPC ou plus classiquement par HTTP.
Je vous conseille de regarder plus en détails [les plugins protoc](https://developers.google.com/protocol-buffers/docs/reference/other) notamment [gogoprotobuf](https://github.com/gogo/protobuf) qui est une autre implémentation de protobuf en Go et [go-proto-validators](https://github.com/mwitkow/go-proto-validators) qui permet de valider les messages protobuf comme des champs obligatoires ou des regex.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
contentType: tutorial-step
tutorial: microservice-avec-go-et-grpc
slug: declaration-du-protobuf
title: Déclaration du Protobuf
---
### Notre fichier Protobuf

Nous allons créer un fichier `translator.proto` dans le dossier `proto`.
```protobuf
syntax = "proto3";
package proto;
```
Nous allons déclarer dans ce fichier un service gRPC. La méthode `Translate` aura comme payload `TranslateRequest` et retournera `TranslateResponse`.
```protobuf
service Translator {
rpc Translate(TranslateRequest) returns (TranslateResponse) {}
}
```
Nous allons maintenant déclarer les messages `TranslateRequest` et `TranslateResponse`.
```protobuf
message TranslateRequest {
string text = 1;
Language language = 2;
}
message TranslateResponse {
string text = 1;
}
```
Petite subtilité ici, les chaînes de caractères ne sont pas compressées avec protobuf. Afin d'optimiser les traitements, on déclare pour `language` que les valeurs possibles sont `en` et `fr`. Pour ce faire on déclare une `enum` `Language`.
```protobuf
enum Language {
en = 0;
fr = 1;
}
```
Notre fichier Protobuf est terminé et devrait ressembler à ça :
```protobuf
syntax = "proto3";
package proto;
enum Language {
en = 0;
fr = 1;
}
message TranslateRequest {
string text = 1;
Language language = 2;
}
message TranslateResponse {
string text = 1;
}
service Translator {
rpc Translate(TranslateRequest) returns (TranslateResponse) {}
}
```
### Génération avec Prototool

Nous allons commencer par générer le fichier de config de Prototool.
```bash
prototool init
```
Nous allons maintenant éditer la config pour qu'il génère notre service gRPC en Go.
```yaml
gen:
go_options:
import_path: translator-service/

plugins:
- name: go
type: go
flags: plugins=grpc
output: .
```
Nous pouvons maintenant générer les fichiers Go.
```bash
prototool gen
```
Dans le dossier `proto` , nous avons maintenant un fichier `translator.pb.go`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
contentType: tutorial-step
tutorial: microservice-avec-go-et-grpc
slug: installation-des-outils
title: Installation des outils
---
### Installer protoc

`protoc` est un générateur qui va lire vos fichiers Protobuf et générer du code.

Si vous êtes sur Linux :
```bash
PROTOC_ZIP=protoc-3.3.0-osx-x86_64.zip
curl -OL https://github.com/google/protobuf/releases/download/v3.3.0/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
rm -f $PROTOC_ZIP
```
Si vous êtes sur Mac OS X :
```bash
brew install protobuf
```
Si vous êtes sur Windows, vous pouvez [télécharger l'exécutable ici](https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-win32.zip).

### Installer prototool

`prototool` est une commande qui va vous permettre d'utiliser plus facilement `protoc` via un fichier yaml. Il intègre aussi un linter et un client gRPC que nous verrons à l'étape 5.

L'installer avec Go :
```bash
go get -u github.com/uber/prototool/cmd/prototool
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
contentType: tutorial-step
tutorial: microservice-avec-go-et-grpc
slug: introduction
title: Introduction
---
### gRPC c'est quoi ?
gRPC a été développé initialement par Google. Il permet de réaliser des clients et serveurs RPC (Remote Procedure Call) via HTTP/2 avec Protocol Buffers.

Je vous invite à lire les articles de notre blog expliquant comment [fonctionne Protobuf](https://blog.eleven-labs.com/fr/presentation-protocol-buffers/) et comment [fonctionne gRPC](https://blog.eleven-labs.com/fr/presentation-grpc/).

### Qu'allons-nous faire ?

Dans ce tutoriel nous allons mettre en place un serveur gRPC en Go utilisant [l'API Translate de Google](https://cloud.google.com/translate/?hl=fr).

Vous pouvez retrouver l'ensemble du code [sur le github des donuts-factory](https://github.com/donuts-factory/translator-service).

Le but est de comprendre :
- la déclaration d'un service gRPC via le fichier protobuf
- la mise en place d'un serveur gRPC
- l'utilisation de l'outil prototool
- la mise en place d'un proxy REST pour pouvoir l'appeler depuis le web

### Prérequis

- Installer [Go 1.9 ou 1.10](https://golang.org/doc/install)
- Créer un dossier `translator-service` dans le dossier `$GOPATH/src`
- Installer [Dep](https://github.com/golang/dep)
Loading

0 comments on commit fd89f84

Please sign in to comment.