Skip to content
This repository was archived by the owner on Jul 9, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions lib/absinthe/compose.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ defmodule Absinthe.Compose do
definition: %{
schema_node: %{__private__: private},
name: name
}
},
context: context
} = resolution

compose = get_in(private, [:meta, :compose])
compose_module = Keyword.fetch!(compose, :from)
opts = Keyword.get(compose, :opts, [])

opts =
Keyword.get(compose, :opts, [])
|> forward_hearders(context)

{query, variables} = Absinthe.Compose.QueryGenerator.render(resolution)

Expand All @@ -24,4 +28,11 @@ defmodule Absinthe.Compose do
def proxy(module, query, variables, opts, resolution) when is_atom(module) do
apply(module, :resolve, [query, variables, opts, resolution])
end

defp forward_hearders(opts, %{headers_to_forward: headers}) do
[headers: Keyword.get(opts, :headers, []) ++ headers]
|> Keyword.merge(opts)
end

defp forward_hearders(opts, _context), do: opts
end
28 changes: 28 additions & 0 deletions lib/absinthe/plug/forward_headers.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Absinthe.Compose.Plug.ForwardHeader do
@moduledoc """
This Plug takes the given headers and add it to Absinthe.Plug context in order to be fowarded
on to the Upstream service on the resolver level.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we proceed with this approach, I think it would be nice if we add how users of this library would plug this plug on their application. It could be here though, something like this:

@moduledoc """
omitted...

In order to use this plug, you need to plug this in your router.

  pipeline :my_pipeline do 
    plug Absinthe.Compose.Plug.ForwardHeader, ["authorization"]
  end
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I think would be better if we specify a key for the headers name, something like: plug Absinthe.Compose.Plug.ForwardHeader, headers: ["authorization"]

My main concern is if this plug starts to receive new arguments in the future (I don't have an example of that). If that happens, a new release of this library would result in a breaking change, requiring all users of this library to update their code before proceeding with the update.

"""
@behaviour Plug

import Plug.Conn

def init(opts), do: opts

@spec call(Plug.Conn.t(), any) :: Plug.Conn.t()
def call(conn, opts) do
headers_to_forward = get_headers(conn, opts)
Absinthe.Plug.put_options(conn, context: %{headers_to_forward: headers_to_forward})
end

defp get_headers(conn, header_names) do
Enum.reduce(header_names, [], fn name, acc ->
name = String.downcase(name)

case get_req_header(conn, name) do
[] -> acc
values -> [{name, values} | acc]
end
end)
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ defmodule AbsintheCompose.MixProject do
""",
links: %{
github: "https://github.com/SpiffInc/absinthe_compose"
},
}
]
end
end
36 changes: 36 additions & 0 deletions test/plug/forward_headers_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Absinthe.Compose.Plug.ForwardHeaderTest do
use ExUnit.Case, async: true
use Plug.Test

alias Absinthe.Compose.Plug.ForwardHeader

setup do
ForwardHeader.init(["Auhtorization", "origin"])

conn =
conn("post", "/", "")
|> put_req_header("auhtorization", "some-token")
Comment thread
frfroes marked this conversation as resolved.
Outdated
|> put_req_header("origin", "www.coolwebsite.com")
|> put_req_header("header-to-ignore", "ignored")

%{
conn: conn
}
Comment thread
frfroes marked this conversation as resolved.
end

test "fowards given headers to abshinte context", %{conn: conn} do
conn = ForwardHeader.call(conn, ["auhtorization", "Origin"])
Comment thread
frfroes marked this conversation as resolved.
Outdated
assert %{context: %{headers_to_forward: headers_to_forward}} = conn.private[:absinthe]

assert [{"origin", ["www.coolwebsite.com"]}, {"auhtorization", ["some-token"]}] =
Comment thread
frfroes marked this conversation as resolved.
Outdated
headers_to_forward

assert length(headers_to_forward) == 2
end

test "ignores non-existent headers", %{conn: conn} do
conn = ForwardHeader.call(conn, ["auhtorization", "origin", "some-giberish"])
Comment thread
frfroes marked this conversation as resolved.
Outdated
assert %{context: %{headers_to_forward: headers_to_forward}} = conn.private[:absinthe]
assert length(headers_to_forward) == 2
end
end