Как сделать редирект 302 в grpc-gateway
Я использую grpc-gateway для размещения HTTP-сервера из моих прототипов. Это прекрасно работает в целом.
Однако для одной специальной конечной точки вместо возврата значения я хочу выполнить перенаправление 302 на изображение, размещенное в s3.
Если вы хотите вернуть ошибку через grpc-gateway, вы можете вернуть ее как
nil, status.Error(codes.Unauthenticated, "Nope")
Интересно, есть ли что-то подобное, чтобы сделать редирект 302?
Насколько я понимаю из этой страницы, это кажется маловероятным. Я надеюсь, что я что-то упустил.
2 ответа
Там нет прямого пути. Но есть обходной путь.
В gRPC нет концепции, подобной 302. Поэтому простые сопоставления кода ошибки не будут работать нормально. Но вы можете переписать перенаправитель ответов для каждого метода, чтобы он redirectURL
из ответа и устанавливает код состояния HTTP и Location
заголовок.
https://grpc-ecosystem.github.io/grpc-gateway/docs/customizingyourgateway.html
Вы также можете использовать среду выполнения. WithForwardResponseOption, который позволяет вам изменять ваш ответ и заголовки ответа.
вот что я сделал, чтобы установить Location
заголовок в ответ.
- Задавать
Location
заголовок в вашем методе GRPC с использованием метаданных. это добавляетGrpc-Metadata-Location
заголовок к вашему ответу.
func (s *Server) CreatePayment(ctx context.Context, in *proto.Request) (*proto.Response, error) {
header := metadata.Pairs("Location", url)
grpc.SendHeader(ctx, header)
return &proto.Response{}, nil
}
- Если
Grpc-Metadata-Location
заголовок существует в ваших заголовках ответов GRPC, установите HTTPLocation
заголовок и код состояния.
func responseHeaderMatcher(ctx context.Context, w http.ResponseWriter, resp proto.Message) error {
headers := w.Header()
if location, ok := headers["Grpc-Metadata-Location"]; ok {
w.Header().Set("Location", location[0])
w.WriteHeader(http.StatusFound)
}
return nil
}
- Установите эту функцию как параметр в
NewServeMux
:
grpcGatewayMux := runtime.NewServeMux(
runtime.WithForwardResponseOption(responseHeaderMatcher),
)
Глядя на код, который вы упомянули, кажется, что он просто отображает коды состояния grpc непосредственно в их ближайшие http-эквиваленты. Похоже, что в спецификации нет кодов, которые действительно отображают http-редирект. Правильно ли я полагаю, что вы используете шлюз для подключения браузера к сервису grpc?
Мое предложение было бы работать перенаправления в протокол как-то. Что, если ответ на определенные методы был что-то вроде:
message HelloResponse {
string reply = 1;
bool shouldRedirect = 2;
string redirectURL = 3;
}
Затем, если получатель может обнаружить это по ответу и перенаправить на клиентскую сторону. Немного менее волшебно, но все же позволяет вам делать перенаправление при необходимости.