Hello!
I have recently discovered that calling Absinthe.Plug.put_options
, in my case to add some information to the context, actually overwrites whatever might have been set as the context before. I have two plugs for my router, one that auths and adds the user to the context, and another that adds a workspace ID to the context. I know I could just combine these plugs but that kind of defeats the point of plugs (modular parts of a pipeline).
Absinthe.Plug.put_options(conn, context: %{authenticated: true, current_user: user})
Absinthe.Plug.put_options(conn, context: %{workspace: current_workspace})
So the question is, is there any way that I could modify the context object instead of overwriting it? I’d be happy to just get the current context, merge the new options, and call put_options with the merged object but I can’t see a great way to get the current context. Only way I can see is to grab it from conn.private.absinthe but that doesn’t feel right.
1 Like
I had the same issue and just ended up merging the context.
e.g. to resolve some subfields in our queries, we need the language passed down to their resolvers like this:
object :search_queries do
@desc "Find products using search terms."
field :search, non_null(:search_result) do
# Store the language on the context for field level resolution
middleware fn res, _ ->
%{res | context: Map.merge(res.context, %{args: res.arguments})}
end
@desc "Search keywords."
arg :keywords, :string, default_value: ""
@desc "Country code."
arg :country, :string, default_value: "US"
@desc "Currency."
arg :currency, :string, default_value: "USD"
@desc "Language."
arg :language, :string, default_value: "EN"
@desc "Page number to return."
arg :page, :integer, default_value: 1
@desc "Number of items per page."
arg :page_size, :integer, default_value: 20
@desc "The width of images (in pixels) to suit the user's phone"
arg :image_width, :integer, default_value: 500
resolve &SearchResolver.search/2
end
end
That makes the language value available at the field level where we need to translate strings.
We do something slightly similar in our global middleware(s). e.g.
%{
res
| middleware:
res.middleware ++
[
{{__MODULE__, :complete},
[
start_time_mono: start_time_mono
]}
]
}
@Francesco PR welcome for an update_options
function. In the short term feel free to grab it from conn.private.
2 Likes
@Catharz thanks for the help 
@benwilson512 I’m definitely keen to try my hand at the PR as soon as I can spare a few hours! But yep just using conn.private is working fine in the meantime