Paginate root object with Absinthe

This is my schema:

defmodule ContentProxyGraphql.Schema.ObjectTypes.Content do
  use Absinthe.Schema.Notation

  import_types Absinthe.Type.Custom
  import_types ContentProxyGraphql.Schema.ObjectTypes.{
    Person,
    Language,
    Publisher
  }

  alias ContentProxyGraphql.Resolvers

  object :content do
    field :type_of, non_null(:string)
    field :name, non_null(:string)
    field :date_created, non_null(:datetime)
    field :date_modified, non_null(:datetime)
    field :learning_resource_type, non_null(:string)
    field :description, :string
    field :thumbnail_url, :string
    field :license, :string
    field :educational_use, :string
    field :interactivity_type, :string
    field :url, :string
    field :author, list_of(:person)
    field :additional_property, list_of(:property_value)
    field :educational_alignment, list_of(:alignment_object)
    field :identifier, non_null(:property_value)
    field :publisher, :publisher
    field :in_language, :language
    field :audience, :education_audience
    field :is_part_of, :content_reference
  end

  object :property_value do
    field :type_of, non_null(:string)
    field :property_id,  non_null(:string)
    field :value, non_null(:string)
  end

  object :education_audience do
    field :type_of, non_null(:string)
    field :education_role, non_null(:string)
  end

  object :alignment_object do
    field :type_of, non_null(:string)
    field :alignment_type, non_null(:string)
    field :educational_framework, non_null(:string)
    field :target_name, non_null(:string)
    field :target_url, :string
  end

  object :content_reference do
    field :type_of, non_null(:string)
    field :identifier, :property_value
  end

  object :content_queries do
    field :contents, list_of(:content) do
      arg :type_of, :string
      resolve &Resolvers.Resources.Content.list/2
    end
  end


end

When I doing a query, I get this result:

I’m struggling to implement absinthe pagination on root object (in my case :content) because all of absinthe examples are about nested objects ( Absinthe.Relay.Connection — absinthe_relay v1.5.2 ). Is there a way to implement root object pagination?

To exemplify my problem, I want this exact pagination

I’m trying this https://gist.github.com/LawJolla/600ee13f42c9dfd9beda449c05a5ebed but no success

You’re very close, you’re just making it harder than you need by employing with. The from_query function already returns a tuple so the smallest change that would work is basically just:

thread_id = get_thread_id(thread)
with  thread <- Messages.find_all_threads_query(thread, user, uuid) do
  Absinthe.Relay.Connection.from_query(thread, &WkGraphql.Repo.all/1, p_args)
else
    {:error, error} -> {:error, error}
    _ -> {:error, "Error fetching Threads"}
end

The with is useless at this point though because it can’t fail, so we can simplify further do:

thread
|> Messages.find_all_theads_query(thread, user, uuid)
|> Absinthe.Relay.Connection.from_query(thread, &WkGraphql.Repo.all/1, p_args)

One final question, how is the source: going to be thread? This is a top level field, unless you’re setting the root value then the source is just an empty map.

Hi @benwilson512
first of all, thank you very much to read my message and answer this post.

I can’t use from_query because my data source is mongodb, I’m trying to use from_slice (https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_slice/3).

I will remove with to make the code cleaner.

About :source , I don’t know the answer, but I’m doing some tests to understand how :source works at this point.

Hi @benwilson512

Works like a charm!

connection field :contents, node_type: :content do
      resolve fn
        pagination_args, _ ->
          Resolvers.Resources.Content.list(pagination_args)
          |> Absinthe.Relay.Connection.from_list(pagination_args)
      end
    end

I’ve used Absinthe.Relay.Connection.from_list just for tests propose. The correct solution is to use from_slice

It is worth noting In this case, source: is unuseful, as you had predict. The source: is used when you are listing associated object ( https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#module-connection )

object :person do
  field :first_name, :string
  connection field :pets, node_type: :pet do
    resolve fn
      pagination_args, %{source: person} ->
        Absinthe.Relay.Connection.from_list(
          Enum.map(person.pet_ids, &pet_from_id(&1)),
          pagination_args
        )
      end
    end
  end
end
2 Likes