Search code examples
c#grpcienumerable

gRPC: Turn a message proto into a List<message> (C# .Net6)


I want to turn a messageResponse from a protocol buffer into a IEnumerable<messageResponse> so in the service will return me an IEnumerable<messageResponse>

Proto I have:

syntax = "proto3";

option csharp_namespace = "ProjectName.Protos";

package Banana;

service Banana {
   rpc GetAllBananas (MessageRequest) returns (ListBananasResponse);
}

//How to Turn this to IEnumerable<> ?
message ListBananasResponse{
    string bananaName = 1;
    string bananaInfo = 2;
}

message MessageRequest{
    string message = 1;
}

And this is my the BananaService.cs

using Grpc.Core;
using ProjectName.Protos;

namespace ProjectName.Services
{

    public class BananaService : Banana.BananaBase
    {
      //The Method should return a IEnumerable list of bananas 
         //want to do Task<IEnumerable<ListBananasResponse>>
      public override Task<ListBananasResponse> GetAllBananas(MessageRequest request, 
      ServerCallContext context)
        {
            var lstbananas = new IEnumerable<ListBananasResponse>();
            return lstbananas;
        }
    }

Is there any way to do this and if so, how to do it? (I'm Using C# .Net6)

Any answer is welcome :)


Solution

  • There's no way of specifying that a protobuf RPC returns a list of responses in one go. There are two options here:

    • Add a message that has a repeated field, and return that from the RPC
    • Use a streaming RPC

    Unless you actually need streaming, I'd strongly advise the former approach. So your .proto file would include a section like this:

    service Banana {
       rpc GetAllBananas (MessageRequest) returns (ListBananasResponse);
    }
    
    message Banana {
        string name = 1;
        string info = 2;
    }
    
    message ListBananasResponse {
        repeated Banana bananas = 1;
    }
    

    You'd then implement the RPC with something like:

    public override Task<ListBananasResponse> GetAllBananas(MessageRequest request, 
        ServerCallContext context)
    {
        var banana1 = new Banana { Name = "name1", Info = "info1" };
        var banana2 = new Banana { Name = "name2", Info = "info2" };
        var response = new ListBananasResponse
        {
            Bananas = { banana1, banana2 }
        };
        return Task.FromResult(response);
    }