Hey everyone

I'm building an API with GRPC which currently looks like this:

serivce OurEndpoint {
   rpc register (RegistrationForFeatureCeeAndDee) returns (stream 
FeatureCeeOrDeeRequest) {}
     
   rpc featureA (FeatureAyeRequest) returns (FeatureAyeReponse) {}
   rpc featureB (FeatureBeeRequest) returns (FeatureBeeResponse) {}
   
   rpc offerFeatureC(FeatureCeeResponse) returns (Confirmation) {}
   rpc offerFeatureD(FeatureDeeResponse) returns (Confirmation) {}
   rpc offerCeeOrDeeFailed(FailureResponse) returns (Confirmation) {}
}


message FeatureCeeOrDeeRequest {
    oneof request {
        FeatureDeeRequest deeRequest = 1;
        FeatureCeeRequest ceeRequest = 2;      
    }
}


message Confirmation {}

Note that features A and B are fairly traditional client-driven 
request-response pairs.

Features C and D are callbacks; the client registers with

I can provide answers to C and D, send me a message and I'll call 
offerFeatureResponse 
> as appropriate.


I don't like this. It makes our application code complex. We effectively 
have to build our own multiplexer for things like offerCeeOrDeeFailed

What I'd really rather do is this:

serivce OurEndpoint {
   rpc register (RegistrationForFeatureCeeAndDee) returns (Confirmation) {}
     
   rpc featureA (FeatureAyeRequest) returns (FeatureAyeReponse) {}
   rpc featureB (FeatureBeeRequest) returns (FeatureBeeResponse) {}  
}
service EndpointClientMustImplement {
   rpc featureC(FeatureCeeRequest) returns (FeatureCeeResponse) {}
   rpc featureD(FeatureDeeRequest) returns (FeatureDeeResponse) {}
}


message RegistrationForFeatureCeeAndDee {
   ConnectionToken name = 1;
}


message Confirmation {}


The problem here is how to go about implementing ConnectionToken and its 
handler. Ideally I'd like some code like this:

//kotlin, which is on the jvm.
override fun register(request: RegistrationForFeatureCeeAndDee, response: 
ResponseObserver<Confirmation>) {
   
    //...
   
    val channel: Channel = ManagedChannelBuilder
            .for("localhost", 5551) // a port shared by the service 
handling this very response
            .build()
           
    val stub: EndpointClientMustImplement = EndpointClientMustImplement.
newBuilder()
            .withServiceNameOrSimilar(request.name)
            .build()
           
    //....
}

What is the best way to go about this?
1. Can I have multiple servers at a single address?
2. Whats the best way to find a service instance by name at runtime rather 
than by a type-derived (and thus by statically bound) name? I suspect the 
BindableService and ServerServiceDefinitions will help me here, but I 
really don't want to mess with the method-table building and the code 
generating system seems opaque. 

I guess my idea solution would be to ask the code generator to generate 
code that is open on its service name, --ideally open on a constructor 
param such that there is no way to instance the service without specifying 
its service name.

Or, perhalps there's some other strategy I should be using? I could of 
course specify port numbers and then instance grpc services once-per-port, 
but that means I'm bounded on the number of ports I'm using by the number 
of active API users I have, which is very strange.

Many thanks!

-Geoff

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/7344c5fc-3c92-4003-aa40-cfb03a27a4c5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to