How to access `conn` from different module?

Hi friends, How can we get conn object in a different module (in my case resolution function of absinthe) ?
I want to get the ip by conn.remote_ip property of conn. But I’m not able to get the conn :grimacing:

Show your code. Propably you didn’t use plug properly. You should use plug to intercept the conn or just pass conn explicitly to your function in the controller’s action.

defmodule MyApp.Schema do
  use Absinthe.Schema
  import Plug.conn
  ...
  ...
  ...
  field :tracking_ip, :string do
    arg: params
   resolve fn {%{context: %{current_user: current_user}} -> 
      IO.inspect conn
   end
end

I want to fetch the ip form conn!

import Plug.Conn would only import the functions inside the Plug.Conn module, not the conn struct from a request.

What you probably want to do is create a “context” plug like here where you can add the ip address to the returned context, such that your resolve function would become

resolve fn _, %{context: %{current_user: current_user, remote_ip: remote_ip}} -> 
  ...
end

The context plug would probably look like this

defmodule YourAppName.Web.Context do
  @behaviour Plug
  import Plug.Conn

  def init(opts) do
    opts
  end

  def call(conn, _opts) do
    case build_context(conn) do
      {:ok, context} ->
        put_private(conn, :absinthe, %{context: context})
      {:error, reason} ->
        conn
        |> send_resp(403, reason)
        |> halt()
      _ ->
        conn
        |> send_resp(400, "Bad Request")
        |> halt()
    end
  end


  # Return the current user context based on the authorization header
  # and remote ip address
  defp build_context(%{req_readers: req_readers, remote_ip: remote_ip}) do
    with "Bearer " <> token <- :proplists.get_value("authorization", req_readers),
         {:ok, current_user} <- authorize(token) do
      {:ok, %{current_user: current_user, remote_ip: remote_ip}}
    end
  end
  
  defp authorize(token) do
    # ... your auth logic
  end
end

Note that remote_ip might be “wrong” if you are behind a load balancer.

2 Likes