Add field level resolvers with hydrate/2 in Absinthe

I’m trying to work with and external schema in Absinthe.

How can I attach a resolve functions to a specific field of a type in a schema, that was imported with import_sdl? In the Absinthe schma DSL I could just do something like this:

object :some_object do
  ...
  field(:name, :string) do
    resolve(fn _, _, _ -> {:ok, "HELLOO"} end)
  end
  ...
end

But when the scema is loaded using import_sdl, I can only rely on the hydrate function to somehow add a field specific resolver. I tried something like this, but for some reason it messed up my entire schema, and Graphiql was no longer able to give info about the schema after I added this function clause:

  def hydrate(%Absinthe.Blueprint.Schema.FieldDefinition{name: "name"}, _ancestors) do
    [
      resolve: {Some.Module, :resolve_name_field}
    ]
  end

It actually works, and it can rewrite the name field, but it also changes something that messes up schema introspection. (Maybe it redefines the name field of some internal object?)

How do I do this properly, without screwing up the schema?
How do I pattern match in hydrate to select that I only want to resolve on some_objects name field?

Can somebody please give me some hint on this?

Hey @sandorbedo your issue is that you’re matching on EVERY field called name instead of just a specific one. You should match on the ancestors list to do eg

  def hydrate(%{name: "name"}, [%{identifier: :some_object} | _]) do
    [
      resolve: {Some.Module, :resolve_name_field}
    ]
  end

So that you’re adding a resolver to the name field of some_object.

That said, I’d consider using this form shown here in the Absinthe tests as it’s a lot more succinct:

In your case it’d look like:

    def hydrate(%Absinthe.Blueprint{}, _) do
      %{
        some_object: %{
          name: [
            {:resolve, fn _, _, _ -> {:ok, "HELOO"} end}
          ]
        },
      }
    end