Dans cet article, nous allons découvrir :
- Le langage Go (Golang)
- Le fonctionnement de gRPC
- La création d’un serveur gRPC en Go
- La génération automatique de clients
- L’utilisation de Docker pour tout orchestrer
1. Introduction à Golang
Go est un langage compilé créé par Google. Son objectif principal est de proposer :
- Un langage simple
- Une compilation rapide
- Des performances proches du C
- Une excellente gestion de la concurrence
Go est aujourd’hui massivement utilisé pour :
- Microservices
- API haute performance
- Infrastructure cloud (Docker, Kubernetes, Traefik…)
2. Installation et création d’un projet Go
Vérifier l’installation
go version
go env
Créer un projet
mkdir mon-projet
cd mon-projet
go mod init mon-projet
Le fichier go.mod est le gestionnaire de dépendances de Go
(similaire à package.json ou composer.json).
3. Structure minimale Go
Créer un fichier main.go :
package main
import "fmt"
func main() {
fmt.Println("Hello Go")
}
Exécuter
go run main.go
Compiler
go build
Contrairement à PHP ou NodeJS, Go produit un binaire exécutable.
4. Introduction à gRPC
gRPC signifie Google Remote Procedure Call.
Il repose sur deux technologies :
- Protocol Buffers → sérialisation des données
- HTTP/2 → transport réseau performant
Pourquoi gRPC ?
- Plus rapide que JSON REST
- Typage fort
- Streaming natif
- Multi-langages
5. Protocol Buffers
On décrit une API via un fichier .proto.
syntax = "proto3";
package ctt;
option go_package = "myhomehub/go/grpc/gen/ctt";
message Result {
int32 total = 1;
int32 win = 2;
int32 lost = 3;
int32 winrate = 4;
}
message GetPlayerResultRequest {
int32 license = 1;
}
message GetPlayerResultResponse {
Result result = 1;
}
service CttService {
rpc GetPlayerResult (GetPlayerResultRequest)
returns (GetPlayerResultResponse);
}
Ce fichier décrit :
- Les messages
- Les requêtes
- Les réponses
- Le service exposé
6. Compilation du proto
protoc ne crée PAS un programme exécutable.
Il génère du code source dans le langage choisi.
protoc \
--go_out=gen/ctt --go_opt=paths=source_relative \
--go-grpc_out=gen/ctt --go-grpc_opt=paths=source_relative \
-I proto/ctt \
proto/ctt/player_result.proto
7. Serveur gRPC en Go
package main
import (
"context"
"log"
"net"
pb "myhomehub/go/grpc/gen/ctt"
"google.golang.org/grpc"
)
type server struct {
pb.UnimplementedCttServiceServer
}
func (s *server) GetPlayerResult(
ctx context.Context,
req *pb.GetPlayerResultRequest,
) (*pb.GetPlayerResultResponse, error) {
return &pb.GetPlayerResultResponse{
Result: &pb.Result{
Total: 10,
Win: 7,
Lost: 3,
Winrate: 70,
},
}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatal(err)
}
grpcServer := grpc.NewServer()
pb.RegisterCttServiceServer(grpcServer, &server{})
log.Println("gRPC server started on :50051")
grpcServer.Serve(lis)
}
8. Client Go gRPC
package main
import (
"context"
"log"
"time"
pb "myhomehub/go/grpc/gen/ctt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
conn, err := grpc.Dial(
"grpc-ctt:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := pb.NewCttServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := client.GetPlayerResult(ctx,
&pb.GetPlayerResultRequest{License: 1234},
)
if err != nil {
log.Fatal(err)
}
log.Println("Winrate:", res.Result.Winrate)
}
9. Client Python gRPC
Installer :
pip install grpcio grpcio-tools
Génération :
python -m grpc_tools.protoc \
-I. \
--python_out=. \
--grpc_python_out=. \
player_result.proto
Client :
import grpc
import player_result_pb2
import player_result_pb2_grpc
channel = grpc.insecure_channel("localhost:50051")
client = player_result_pb2_grpc.CttServiceStub(channel)
response = client.GetPlayerResult(
player_result_pb2.GetPlayerResultRequest(license=1234)
)
print(response.result.winrate)
10. Dockerisation du serveur gRPC
FROM golang:1.23-alpine AS builder
RUN apk add --no-cache protobuf
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
WORKDIR /app
COPY . .
RUN protoc \
--go_out=gen/ctt --go_opt=paths=source_relative \
--go-grpc_out=gen/ctt --go-grpc_opt=paths=source_relative \
-I proto/ctt \
proto/ctt/player_result.proto
RUN go mod tidy
RUN go build -o server ./services/ctt
FROM alpine:3.20
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 50051
CMD ["./server"]
11. Documentation dynamique gRPC
Grâce à grpcui, on peut exposer automatiquement la documentation interactive :
grpcui:
image: fullstorydev/grpcui
command:
- "-plaintext"
- "grpc-ctt:50051"
Accessible ensuite via :
https://doc.thiebault.test
12. Architecture finale
Client Go / Python / Laravel
↓
gRPC
↓
Go gRPC Server
↓
MySQL
Conclusion
Go + gRPC permet de construire des microservices extrêmement performants, typés et multi-langages.
Un seul fichier .proto devient la source de vérité
pour tous les clients et serveurs.
C’est aujourd’hui une des architectures les plus modernes pour construire des plateformes distribuées.