Aperçu de gRPC dans Blazor

Aperçu de gRPC dans Blazor

En travaillant sur Blazor, j’ai commencé à m’intéresser à gRPC pour la communication entre le serveur et le client. Je vais donc dans cet article faire un petit aperçu de gRPC avec un exemple simple de mise en place dans un projet Blazor serveur.

Le code d’illustration est présent sur github : https://github.com/niou128/PocgRPC

Qu’est-ce que gRPC

La première question légitime à se poser est bien sûr : Qu’est-ce donc que gRPC.

Une des méthodes les plus communes pour échanger des données entre le client et le serveur consiste à utiliser le JSON-over-http. Pour faire simple, le client crée une requête HTTP à une URL prédéterminée avec une méthode précise. Il envoie des données au format JSON. Le serveur procède au traitement et répond avec un code HTTP et des données JSON. Cela fonctionne globalement très bien, mais avec un léger souci : le format JSON peut être lourd et peu optimisé pour la bande passante.

gRPC est un framework open source performant développé par Google (Remote Procedure Call). Il est une alternative au JSON-over-http. Il utilise le protocole HTTP/2 pour le transport. Il permet la transmission bidirectionnelle, l’authentification, etc. Il dispose de bibliothèques pour de nombreux langages. https://grpc.io/.

Il est optimisé pour un faible trafic réseau en envoyant des messages binaires sérialisés.

Il s’agit d’un framework très rapide et évolutif.

Si on compare REST avec gRPC, on constate que REST semble plus limité. En effet, alors que vous disposez globalement de GET, PUT, POST et DELETE en REST, vous pouvez définir n’importe quel type de fonction avec gRPC

Lors de la création du service gRPC, vous définissez un fichier .proto qui est indépendant des langages et qui est une description d’un ensemble de services RPC ainsi que leur format de données. À partir de ce fichier, il est possible de générer du code pour le client et le serveur dans une multitude de langages différents.

Au moment de l’exécution, gRPC s’occupe de la (dé)sérialisation de vos données et envoie/reçoit des messages dans un format efficace (protobuf par défaut).

Création du serveur

Dans visual studio 2019, il faut créer un projet gRPC Service.

J’ai ensuite choisi .NET Core 3.1.

Ce projet sera la partie serveur de notre application.

La mise en place d’un service gRPC est aussi simple que cela.

Le projet étant créé, on peut se pencher un peu plus sur le contenu. Dans l’explorateur de solution, on constate la présence d’un dossier Protos contenant un fichier greet.proto.

Ce fichier sera le contrat de service de notre API.

syntax = "proto3";

option csharp_namespace = "PocGrpc";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

Dans l’exemple, le service Greeter à une seule interface SayHello qui prend en paramètre un HelloRequest et qui retourne un HelloReply.

La définition du message HelloRequest définie un champ name et HelloReply défini un champ message.

La définition du nom et du nombre est très importante au départ. Ils sont uniques et ne changent pas, car ils sont utilisés pour identifier les champs.

La classe GreeterService du dossier Services utilise cette définition.

Client

Pour le client, j’ajoute à la solution un projet Blazor serveur.

Dans le client, il faut ajouter 3 paquets NuGet :

  • Google.Protobuf
  • Grpc.Net.Client
  • Grpc.Tools

Ensuite il faut copier le dossier Protos contenant le fichier greet.proto du serveur vers le client.

Il faut également modifier le csproj afin d’ajouter un itemgroup référençant le protobuf.

<ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
  </ItemGroup> 

Ensuite j’ajoute une nouvelle classe Index.razor.cs héritant de ComponentBase et qui contiendra le code C# de ma vue.

Dans ce fichier on ajoute le code suivant :

protected string Greeting;

        protected async Task SayHello()
        {
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = new Greeter.GreeterClient(channel);

            var reply = await client.SayHelloAsync(new HelloRequest { Name = "Blazor gRPC Client" });
            Greeting = reply.Message;

            await channel.ShutdownAsync();
        }

Et je remplace le code de la page index.razor par celui-ci :

@page "/"
@inherits IndexBase

<h1>Aperçu gRPC</h1>

<button class="btn btn-primary" @onclick="@SayHello">Say Hello</button>

<hr />

<p>@Greeting</p>

Revenons un peu sur le code. La propriété Greeting sert à recueillir le message retourné par l’appel au serveur et l’affiche à l’écran lorsque l’on clique sur le bouton « Say Hello ».

La méthode SayHello réalise l’appel.

D’abord on crée un canal gRPC vers le serveur. On crée ensuite une instance de GreeterClient. Cette classe est générée automatiquement en utilisant le fichier greet.proto.

Avec cette instance, on peut appeler les méthodes définies dans le fichier proto. Ici on appelle HelloRequest en spécifiant le paramètre nom.

Et quand on clique sur le bouton …

La réponse s’affiche.

Il s’agit bien sûr ici d’un simple aperçu de gRPC mais l’on a pu voir à travers cet article, la mise en place d’un service gRPC et l’intégration du service dans une application Blazor.

Vous pouvez également approfondir le sujet en consultant la documentation de Microsoft.

Laisser un commentaire