У меня есть GRPC API, где после рефакторинга несколько пакетов были переименованы. Это включает в себя объявление package
в одном из наших файлов прото, которое определяет API. Примерно так:
package foo;
service BazApi {
rpc FooEventStream(stream Ack) returns (stream FooEvent);
}
, который был изменен на
package bar;
service BazApi {
rpc FooEventStream(stream Ack) returns (stream FooEvent);
}
На стороне сервера реализовано использование grpc-java
с scala и monix сверху.
Это всеотлично работает для клиентов, которые используют новые файлы proto, но для старых клиентов, которые были построены поверх старых файлов proto, это вызывает проблемы: UNIMPLEMENTED: Method not found: foo.BazApi/FooEventStream
.
Фактический формат данных сообщений, передаваемых черезGRPC API не изменился, только пакет.
Поскольку нам необходимо поддерживать обратную совместимость, я искал способ заставить старых клиентов работать, сохраняя изменение имени.
Я надеялся сделать эту работу с помощью универсальногоServerInterceptor
, который сможет проверить входящий вызов, увидеть, что он поступил от старого клиента (у нас есть версия клиента в заголовках) и перенаправить / переслать его переименованному сервису. (Поскольку изменилось только название пакета, это легко понять, например, foo.BazApi/FooEventStream
-> bar.BazApi/FooEventStream
)
Однако, похоже, не существует элегантного способа сделать это. Я думаю, что это возможно, запустив новый ClientCall
для правильной конечной точки, а затем обработав ServerCall
внутри перехватчика, делегировав ClientCall
, но это потребует связки кода для правильной обработки unary / clientStreaming /serverStreaming / bidiStreaming звонки.
Есть ли лучший способ сделать это?