The list of middleware for a field is managed here: absinthe/lib/absinthe/blueprint/schema/field_definition.ex at main · absinthe-graphql/absinthe · GitHub I meant to link that in my original reply but was on mobile and apparently messed up the link!
Your bug with def middleware
is that you are pattern matching on the object identifier not the field identifier. What you want to do is set the resolver on a field named :create_item
on the object named :mutation
so what you need is:
def middleware(middleware, %{identifier: :create_item}, _object) do
IO.puts("MANUALLY DEFINING RESOLUTION VIA MIDDLEWARE")
middleware ++ [{{Absinthe.Resolution, :call}, &create_item/3}]
end
Back to the question of pipeline modifiers though, if you set [{{Absinthe.Resolution, :call}, &create_item/3}]
on the middleware
list of the FieldDefinition
you should be good to go. Here’s’ a complete example:
defmodule MySchemaBuilder do
alias Absinthe.{Phase, Pipeline, Blueprint}
def pipeline(pipeline) do
Pipeline.insert_after(pipeline, Phase.Schema.TypeImports, __MODULE__)
end
def run(blueprint, _) do
blueprint = Blueprint.prewalk(blueprint, fn
%Blueprint.Schema.FieldDefinition{} = field_def ->
set_middleware(field_def)
node ->
node
end)
{:ok, blueprint}
end
def set_middleware(%{identifier: :create_item} = field_def) do
Map.update!(field_def, :middleware, fn middleware ->
middleware ++ [{{Absinthe.Resolution, :call}, &create_item/3}]
end)
end
def set_middleware(field_def) do
field_def
end
# this could be anywhere, doesn't need to be in this module.
def create_item(_parent, _args, _context) do
IO.puts("CREATING THE ITEM....")
{:ok, %{id: "my-id", name: "my name"}}
end
end
defmodule TestSchema do
use Absinthe.Schema
@schema_provider Absinthe.Schema.PersistentTerm
@pipeline_modifier MySchemaBuilder
query do
end
mutation do
@desc "Create an item"
field :create_item, type: :item do
arg(:id, non_null(:string))
arg(:name, :string)
end
end
@desc "An item"
object :item do
field(:id, :id)
field(:name, :string)
end
end
Absinthe.run("mutation { createItem(id: \"1\", name: \"foo\") { id } }", TestSchema)
CREATING THE ITEM....
{:ok, %{data: %{"createItem" => %{"id" => "my-id"}}}}
As a small note, you’ll notice I set @schema_provider Absinthe.Schema.PersistentTerm
. This is likely going to be the standard in the next Absinthe release, as it is much more flexible when dealing with middleware. The current default essentially has to store the middleware via a complicated macro system to deal with anonymous functions, but persistent_term
has no such limitations, and is actually faster too!