elixir-grpc / grpc

An Elixir implementation of gRPC
https://hex.pm/packages/grpc
Apache License 2.0
1.39k stars 212 forks source link

No way to reliably get response headers from a ClientInterceptor #388

Open leo-fresha opened 2 months ago

leo-fresha commented 2 months ago

Is your feature request related to a problem? Please describe. I'm trying to read response headers from a ClientInterceptor, but I can't find a way that doesn't rely on forcing the users to call their stub methods with return_headers: true.

Example, an interceptor that sets a value in the Process dictionary based on a response header:

defmodule ProcessValueFromHeadersInterceptor do
  @behaviour GRPC.ClientInterceptor

  @impl true
  def init(_), do: nil

  @impl true
  def call(stream, req, next, _opts) do
    # As far as I can tell, the only way to get the headers is out of the result of calling the next processor
    # But this depends on whether the stub method was called with `return_headers: true`,
    # which is outside of the interceptor control
    case next.(stream, req) do
      {:ok, _resp, headers} = result ->
        Process.set(:special_header_value, Map.get(headers, "special-header", nil))
        result
      # I have no way of reading the response headers from my interceptor in this case,
      # even if the server sent some
      result ->
        result
     end
  end
end

Describe the solution you'd like Being able to easily and consistently read response headers from a ClientInterceptor.

Describe alternatives you've considered I've tried looking in the source code for workaround ways of reading the headers, but I found no easy options. Maybe Stub.recv/2, but not sure whether that is idempotent or calling it from my interceptor could break the request processing.