+protobuf@googlegroups.com who will be able to contribute more on the
protocol buffers side of the discussion

On Mon, Nov 21, 2016 at 2:48 PM, Jesús García Crespo <je...@sevein.com>
wrote:

> First, I would like to say thanks to all of you for the great job!
>

Aww, you're very welcome!


> I'm trying to wire two Python apps using grpcio 1.0.1. In the scenario
> that I'm going to describe below, the client asks for a determined book and
> the server wants to communicate that the book has not ben found. What would
> be the current way to do that with the following proto?
>
> service Library {
>   rpc BookGet(BookGetRequest) returns (BookGetResponse)
> }
>
> message Book {
>   string id = 1;
> }
>
> message BookGetRequest {
>   string id = 1;
> }
>
> message BookGetResponse {
>   Book book = 1;
> }
>

I think the problem here is that the way your messages model your data
doesn't allow for you to represent "no book was found" as a first-class
concept. You could fake it with a sentinel value for the id of the
not-really-found found Book (the empty string, or the string "this id
represents a book not having been found", or something else), but I suspect
that the first-class thing to do would be for BookGetResponse to have a
more complicated type <https://en.wikipedia.org/wiki/Algebraic_data_type>
for its internal field - possibly a oneof
<https://developers.google.com/protocol-buffers/docs/proto#using-oneof>
that can communicate exactly one of the id of a found book or the fact that
the book was not found.

I've tried the following snippet but it won't work because I can't return
> `None` or the channel will fail to serialize the response:
>
> class LibraryServer(object):
>     def BookGet(self, request, context):
>         """ Book not found. """
>         context.set_code(grpc.StatusCode.NOT_FOUND)
>

Yep <https://github.com/grpc/grpc/issues/8672>. I go back and forth on how
and whether that should be made to work.

If I return an empty message *and* set the status code to NOT_FOUND then I
> see an internal exception (message = "_Rendezvous of RPC that terminated
> with (StatusCode.NOT_FOUND, )") is raised on the client side:
>
> class LibraryServer(object):
>     def BookGet(self, request, context):
>         """ Book not found. """
>         context.set_code(grpc.StatusCode.NOT_FOUND)
>

Non-OK status codes always cause exceptions to be raised on the invocation
side of an RPC. If you like you can incorporate that into the semantics of
your application-level protocol but I advise against it because it strikes
me as likely to make actual gRPC-level errors more difficult to handle.

I've also attempted these two approaches:
>
> class LibraryServer(object):
>     def BookGet(self, request, context):
>         """ Book not found. """
>         return library_mcp2.BookGetResponse()
>
> class LibraryServer(object):
>     def BookGet(self, request, context):
>         """ Book not found. """
>         return library_mcp2.BookGetResponse(book=None)
>
> However, this is what I am seeing on the client:
>
> resp = self.stub.BookGet(library_pb2.BookGetRequest(id='12345'))
> resp is None          # False
> resp.book is None     # False
> resp.book.id is None  # False
> resp.book.id == ''    # True
>
> So I could only make use of the last assertion but that seems far from
> ideal, right?
>

I think this has to do with the changes in Protocol Buffers 3 and how
fields and messages are never "not present" any more.

What am I doing wrong?
>

Probably nothing is wrong in the strictest sense; I think it's more a
matter of shaping your messages so that they more clearly and more readily
reflect the semantics of your application-level protocol.

Thank you for your help!
>

Thank you for writing!
-N

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at https://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to