nathanl
How to set up cursor-based pagination with Absinthe?
Does anybody have a good guide for setting up cursor-based pagination, as recommended in The GraphQL docs, using Absinthe?
Most Liked
nathanl
I created a library (only on GitHub for now) to support keyset pagination with absinthe_relay. It’s basically a drop-in replacement in your resolver. An example of paginating a usersConnection:
# in your resolver function
AbsintheRelayKeysetConnection.from_query(
ecto_users_query,
&MyRepo.all/1,
# these args would come from the API user
%{
sorts: [%{name: :desc}, %{id: :desc}],
first: 10,
after: "0QTwn5SRWyJNbyIsMjZd"
},
# you would hard-code this configuration
%{unique_column: :id}
)
The reason a unique_column is specified here is to be a “tie breaker” to ensure a unique value for sorting and paginating. See the moduledocs for more details.
If using this, you might put (for example) under your usersConnection:
arg(:sorts, list_of(:user_order_by))
You’d use user_order_by to define the ways you allow sorting for that record type. (You might want to consider what index support you have or need.)
input_object :user_order_by do
@desc "By email"
field(:email, :sort_direction)
@desc "By first name"
field(:first_name, :sort_direction)
# etc
end
:sort_direction is a simple enum type:
enum :sort_direction do
@desc "Ascending (for example, 1,2,3 or a,b,c)."
value(:asc)
@desc "Descending (for example, 3,2,1 or c,b,a)."
value(:desc)
end
@benwilson512 I’d love to contribute this to absinthe_relay | Hex if you’re interested. If not, I might release it as a separate package.
c13e
@nathanl not a guide per-se but some examples from other open source Elixir codebases that may help you:
-
With Absinthe Relay
-
Without Absinthe Relay
jeroenvisser101
Hey Nathan! That library is great! I’ve some changes I plan to send as a PR (behaviour for Cursor to allow custom cursor implementations, making and marking the default Cursor as “tamper-resistant”, rather than tamper-proof, using Ecto’s dynamic/2 to allow > 3). Still working on some things, including adding tests for a NaiveDateTime sort, and I’m thinking of allowing the key for sorts to be configurable, although this could also be changed in the resolvers before calling from_query/4.
I’m also planning some tests on nullable columns, to see how it affects sorting (IIRC, == nil isn’t allowed in Ecto, and is_nil/1 should be used instead). Maybe this will be outside the scope though, given that asc and desc don’t cover the cases for all possible sorts:
:asc:asc_nulls_last:asc_nulls_first:desc:desc_nulls_last:desc_nulls_first
And I’m not sure if it makes sense to allow all these cases.
nathanl
FYI - this library is now published at absinthe_relay_keyset_connection | Hex
slouchpie
I don’t have a guide but I recently made a demo project that had cursor based pagination using Relay. Absinthe Relay image upload with Expo React Native







