How to do a 302 redirect in grpc-gateway

grpc-gateway-cors
grpc headers
grpc-gateway openapi
grpc-gateway error handling
grpc-gateway query parameters
grpc-gateway streaming
grpc api gateway
grpc java rest 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.

There's no straightforward way. But there's a workaround.

There's no conception in gRPC similar to 302. So simple error code mappings won't work fine. But you can overwrite a response forwarder per method so that it extracts redirectURL from the response and sets the HTTP status code and Location header.

https://grpc-ecosystem.github.io/grpc-gateway/docs/customizingyourgateway.html#replace-a-response-forwarder-per-method

Returning 302 redirect as response � Issue #607 � grpc-ecosystem , Hi, I am looking for a way to return 302 redirects to another URL as a response from grpc-gateway. In my research, I couldn't find a way to do it. 302 redirects (temporary redirects) are not often used because in most cases a 301 redirect (permanent redirect) is a better choice. So, what is the advantage of a 302 temporary redirect? A 302 redirect will not permanently pass the reputation and credibility of the original URL to the new URL.

you could also use runtime. 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),
)

Customizing your gateway, You can have Elasticsearch-style ?pretty support in your gateway's endpoints as follows: Mapping from HTTP request headers to gRPC client metadata. We will be taking a look at temporary redirects. If you’d like to learn how to utilize a permanent redirect, please consult our guide which covers this in detail: Set a permanent (301) redirect using .htaccess. How do I create a temporary redirect? The first thing you’ll need to do (if you haven’t already) is create an .htaccess file.

Looking at the code you mentioned, it appears to be simply mapping the grpc status codes directly to their closest http equivalents. It doesn't appear that there are any codes in the spec that really map to an http redirect. Am I correct in assuming you are using the gateway to connect a browser to a grpc service?

My suggestion would be to work redirects into the protocol somehow. What if the response to certain methods was something like:

message HelloResponse {
  string reply = 1;
  bool shouldRedirect = 2;
  string redirectURL = 3;
}

Then if the receiver could detect that from the response and redirect client-side. A little less magical, but still lets you do the redirect if needed.

CHANGELOG.md - grpc-ecosystem/grpc-gateway, Errors in response streams do not go through the registered error handler #584 Mac OS X - Note about your tutorial #787; Returning 302 redirect as response� How to do internal linking, tagging, 301and 302 redirection? | On page SEO optimization part -2

Redirects, Host Redirect. To effect an HTTP 301 Redirect , the Mapping must set host_redirect to true , with service set to the host to which the client should be redirected:. 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

502 Bad Gateway, Note: A Gateway might refer to different things in networking and a 502 error is usually not something you can fix, but requires a fix by the web� The following steps explain how to get more creative with redirects using cPanel: Log into cPanel using the details your host gave you when you first signed up. Scroll to the Domains section and click Redirects. Choose the type of redirect you want. Redirect choices are 301 and 302.

How to return a 302 with Location header using API Gateway and , How can you map your Lambda success response to 302 with a Like a lot of other things with API Gateway it's easy to do but not very obvious. of a 302 response with the Location header set to the redirect location:� Let me start off with a simple assertion. 404 redirects are bad. They are a terrible user experience and the search bots will penalize you meaningfully for it. 404s occur when a page is deleted from the site and the server, but links to the page and bookmarks still exist. When a user calls that page from the browser, the server returns a 404 Page Not Found. If the search bot gets a 404 a few

Comments
  • I am running into the same use-case but how can one extract redirectURL from the message? If I do resp.redirectURL the compiler tells me that proto.Message does not implement that. Do I have to do some casting first, or similar?
  • @Markus any solution to this?
  • Hi, that's one option, however, my intention is to use this endpoint directly as a part of <img src="https://host/endpoint" /> without processing on the frontend.
  • Then you are probably more limited. All I can think of is modifying the gateway with the feature you want.
  • @captncraig can this be not done on grpc server side before forwarding response?
  • @UmutBenzer What did you end up doing?
  • I ended up implementing our logic on the client side. In one request I get the URL for the image and in the second request, we get the image itself by using the response of the first request. This was implemented before I learned that such a thing WithOutgoingHeaderMatcher existed. I don't know if that would've been worked for me or not.