Serviços do gRPC com C#

Este documento descreve os conceitos necessários para gravar aplicativos gRPC em C#. Os tópicos abordados aqui se aplicam a aplicativos gRPC baseados em C-core e baseados em ASP.NET Core.

arquivo proto

O gRPC usa uma abordagem de contrato primeiro para o desenvolvimento de API. Os buffers de protocolo (protobuf) são usados como a linguagem IDL por padrão. O arquivo .proto contém:

  • A definição do serviço do gRPC.
  • As mensagens enviadas entre clientes e servidores.

Para obter mais informações sobre a sintaxe de arquivos do Protobuf, consulte Criar mensagens do Protobuf para aplicativos .NET.

Por exemplo, considere o arquivo greet.proto usado em Introdução ao serviço do gRPC:

  • Define um serviço Greeter.
  • O serviço Greeter define uma chamada SayHello.
  • SayHello envia uma mensagem HelloRequest e recebe uma mensagem HelloReply:
syntax = "proto3";

option csharp_namespace = "GrpcGreeter";

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;
}

Se você quiser ver os comentários de código traduzidos para idiomas diferentes do inglês, informe-nos neste problema de discussão do GitHub.

Adicionar um arquivo .proto a um aplicativo C#

O arquivo .proto é incluído em um projeto adicionando-o ao grupo de itens <Protobuf>:

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

Por padrão, uma referência <Protobuf> gera um cliente concreto e uma classe base de serviço. O atributo GrpcServices do elemento de referência pode ser usado para limitar a geração de ativos em C#. As opções de GrpcServices válidas são:

  • Both (padrão quando não estiver presente)
  • Server
  • Client
  • None

Suporte para ferramentas de C# para arquivos .proto

O pacote de ferramentas Grpc.Tools é necessário para gerar os ativos em C# dos arquivos .proto. Os ativos gerados (arquivos):

  • São gerados conforme necessário sempre que o projeto é compilado.
  • Não são adicionados ao projeto nem verificados no controle do código-fonte.
  • São um artefato de compilação contido no diretório obj.

Esse pacote é exigido pelos projetos do servidor e do cliente. O metapacote Grpc.AspNetCore inclui uma referência a Grpc.Tools. Os projetos de servidor podem adicionar Grpc.AspNetCore usando o Gerenciador de Pacotes no Visual Studio ou adicionando um <PackageReference> ao arquivo de projeto:

<PackageReference Include="Grpc.AspNetCore" Version="2.32.0" />

Os projetos do cliente devem referenciar diretamente Grpc.Tools junto com os outros pacotes necessários para usar o cliente gRPC. O pacote de ferramentas não é necessário em runtime e, portanto, a dependência é marcada com PrivateAssets="All":

<PackageReference Include="Google.Protobuf" Version="3.18.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.40.0">
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
  <PrivateAssets>all</PrivateAssets>
</PackageReference>

Ativos do C# gerados

O pacote de ferramentas gera os tipos C# que representam as mensagens definidas nos arquivos .proto incluídos.

Para ativos do lado do servidor, um tipo base de serviço abstrato é gerado. O tipo base contém as definições de todas as chamadas gRPC contidas no arquivo .proto. Crie uma implementação de serviço concreta que deriva desse tipo base e implemente a lógica para as chamadas gRPC. Para o greet.proto, o exemplo descrito anteriormente, um tipo abstrato GreeterBase que contém um método virtual SayHello é gerado. Uma implementação concreta GreeterService substitui o método e implementa a lógica que manipula a chamada gRPC.

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

Para ativos do lado do cliente, um tipo de cliente concreto é gerado. As chamadas gRPC no arquivo .proto são convertidas em métodos no tipo concreto, que podem ser chamados. Para o greet.proto, o exemplo descrito anteriormente, um tipo concreto GreeterClient é gerado. Chame GreeterClient.SayHelloAsync para iniciar uma chamada gRPC para o servidor.

// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
                  new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

Por padrão, os ativos de servidor e de cliente são gerados para cada arquivo .proto incluído no grupo de itens <Protobuf>. Para garantir que apenas os ativos do servidor sejam gerados em um projeto do servidor, o atributo GrpcServices é definido como Server.

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

Da mesma forma, o atributo é definido como Client em projetos de cliente.

Recursos adicionais

Este documento descreve os conceitos necessários para gravar aplicativos gRPC em C#. Os tópicos abordados aqui se aplicam a aplicativos gRPC baseados em C-core e baseados em ASP.NET Core.

arquivo proto

O gRPC usa uma abordagem de contrato primeiro para o desenvolvimento de API. Os buffers de protocolo (protobuf) são usados como a linguagem IDL por padrão. O arquivo .proto contém:

  • A definição do serviço do gRPC.
  • As mensagens enviadas entre clientes e servidores.

Para obter mais informações sobre a sintaxe de arquivos do Protobuf, consulte Criar mensagens do Protobuf para aplicativos .NET.

Por exemplo, considere o arquivo greet.proto usado em Introdução ao serviço do gRPC:

  • Define um serviço Greeter.
  • O serviço Greeter define uma chamada SayHello.
  • SayHello envia uma mensagem HelloRequest e recebe uma mensagem HelloReply:
syntax = "proto3";

option csharp_namespace = "GrpcGreeter";

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;
}

Se você quiser ver os comentários de código traduzidos para idiomas diferentes do inglês, informe-nos neste problema de discussão do GitHub.

Adicionar um arquivo .proto a um aplicativo C#

O arquivo .proto é incluído em um projeto adicionando-o ao grupo de itens <Protobuf>:

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

Por padrão, uma referência <Protobuf> gera um cliente concreto e uma classe base de serviço. O atributo GrpcServices do elemento de referência pode ser usado para limitar a geração de ativos em C#. As opções de GrpcServices válidas são:

  • Both (padrão quando não estiver presente)
  • Server
  • Client
  • None

Suporte para ferramentas de C# para arquivos .proto

O pacote de ferramentas Grpc.Tools é necessário para gerar os ativos em C# dos arquivos .proto. Os ativos gerados (arquivos):

  • São gerados conforme necessário sempre que o projeto é compilado.
  • Não são adicionados ao projeto nem verificados no controle do código-fonte.
  • São um artefato de compilação contido no diretório obj.

Esse pacote é exigido pelos projetos do servidor e do cliente. O metapacote Grpc.AspNetCore inclui uma referência a Grpc.Tools. Os projetos de servidor podem adicionar Grpc.AspNetCore usando o Gerenciador de Pacotes no Visual Studio ou adicionando um <PackageReference> ao arquivo de projeto:

<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />

Os projetos do cliente devem referenciar diretamente Grpc.Tools junto com os outros pacotes necessários para usar o cliente gRPC. O pacote de ferramentas não é necessário em runtime e, portanto, a dependência é marcada com PrivateAssets="All":

<PackageReference Include="Google.Protobuf" Version="3.11.4" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.28.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

Ativos do C# gerados

O pacote de ferramentas gera os tipos C# que representam as mensagens definidas nos arquivos .proto incluídos.

Para ativos do lado do servidor, um tipo base de serviço abstrato é gerado. O tipo base contém as definições de todas as chamadas gRPC contidas no arquivo .proto. Crie uma implementação de serviço concreta que deriva desse tipo base e implemente a lógica para as chamadas gRPC. Para o greet.proto, o exemplo descrito anteriormente, um tipo abstrato GreeterBase que contém um método virtual SayHello é gerado. Uma implementação concreta GreeterService substitui o método e implementa a lógica que manipula a chamada gRPC.

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

Para ativos do lado do cliente, um tipo de cliente concreto é gerado. As chamadas gRPC no arquivo .proto são convertidas em métodos no tipo concreto, que podem ser chamados. Para o greet.proto, o exemplo descrito anteriormente, um tipo concreto GreeterClient é gerado. Chame GreeterClient.SayHelloAsync para iniciar uma chamada gRPC para o servidor.

static async Task Main(string[] args)
{
    // The port number(5001) must match the port of the gRPC server.
    using var channel = GrpcChannel.ForAddress("https://localhost:5001");
    var client = new Greeter.GreeterClient(channel);
    var reply = await client.SayHelloAsync(
                      new HelloRequest { Name = "GreeterClient" });
    Console.WriteLine("Greeting: " + reply.Message);
    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}

Por padrão, os ativos de servidor e de cliente são gerados para cada arquivo .proto incluído no grupo de itens <Protobuf>. Para garantir que apenas os ativos do servidor sejam gerados em um projeto do servidor, o atributo GrpcServices é definido como Server.

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

Da mesma forma, o atributo é definido como Client em projetos de cliente.

Recursos adicionais