Declarative gRPC unary server methods currently support Res method(Req) and void method(Req, StreamObserver<Res>). The direct-return form cannot represent an absent lookup result: returning null makes the generated registration pass null to StreamObserver.onNext, while returning Optional<Res> is rejected because code generation validates Optional itself as the protobuf response type.
@Grpc.Unary("GetBook")
Optional<Book> getBook(GetBookRequest request);
The wrapped Book type should be validated against the proto method output type. A present value should be emitted as the unary response. An empty value must produce a defined non-OK gRPC status (for example NOT_FOUND), because a unary call cannot complete successfully without a response message. The generated binding must never pass null to StreamObserver.onNext; a null return should fail with a deterministic status and useful diagnostic.
Keep the existing StreamObserver signature available when applications need custom statuses or trailers. Add code-generation and end-to-end tests for present, empty, and null results, and document the new signature and empty-result mapping.
Declarative gRPC unary server methods currently support
Res method(Req)andvoid method(Req, StreamObserver<Res>). The direct-return form cannot represent an absent lookup result: returningnullmakes the generated registration passnulltoStreamObserver.onNext, while returningOptional<Res>is rejected because code generation validatesOptionalitself as the protobuf response type.The wrapped
Booktype should be validated against the proto method output type. A present value should be emitted as the unary response. An empty value must produce a defined non-OK gRPC status (for exampleNOT_FOUND), because a unary call cannot complete successfully without a response message. The generated binding must never passnulltoStreamObserver.onNext; a null return should fail with a deterministic status and useful diagnostic.Keep the existing
StreamObserversignature available when applications need custom statuses or trailers. Add code-generation and end-to-end tests for present, empty, and null results, and document the new signature and empty-result mapping.