Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a 302 redirect in grpc-gateway

I use grpc-gateway to host an HTTP server out of my proto definitions. It works great overall.

However, for one special endpoint, instead of returning a value back, I want to do a 302 redirect to an image hosted in an s3.

If you want to return an error via grpc-gateway, you can return it like

nil, status.Error(codes.Unauthenticated, "Nope")

I wonder if there is something similar to do a 302 redirect?

As far as I get from this page it seems unlikely. I hope I overlooked something.

like image 657
Umut Benzer Avatar asked Apr 17 '18 13:04

Umut Benzer


People also ask

Does a 302 automatically redirect?

What is an HTTP 302? The 302 status code is a redirection message that occurs when a resource or page you're attempting to load has been temporarily moved to a different location. It's usually caused by the web server and doesn't impact the user experience, as the redirect happens automatically.

What is a web 302 redirect?

The HyperText Transfer Protocol (HTTP) 302 Found redirect status response code indicates that the resource requested has been temporarily moved to the URL given by the Location header.

What is a gRPC Gateway?

Grpc-gateway is a server that routes HTTP/1.1 request with JSON bodies to gRPC handlers with protobuf bodies. This means you can define your entire API as gRPC methods with requests and responses defined as protobuf, and then implement those gRPC handlers on your API server.


1 Answers

you could also use WithForwardResponseOption method which allows you to modify your response and response headers.

here is what I did to set Location header in response.

  1. Set Location header in your GRPC method using metadata. this adds Grpc-Metadata-Location header to your response.
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
}
  1. If Grpc-Metadata-Location header exists in your GRPC response headers, Set HTTP Location header and status code as well.
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
}
  1. Set this func as an Option in NewServeMux:
grpcGatewayMux := runtime.NewServeMux(
    runtime.WithForwardResponseOption(responseHeaderMatcher),
)
like image 131
rezam Avatar answered Sep 30 '22 14:09

rezam