Disable Pagination in Ash


Here's how to disable pagination in Ash framework for Elixir.

Scenario

I'm using ash_graphql and trying to get a query to work as desired. A review entity has many projects, via a many_to_many relationship.

I want to query a review that will only ever have a handful of projects, so the join to project never needs paginated. I have pagination on for the :read action of projects, which is useful in a different context.

Offset pagination

Offset pagination is "get me the n number records after the nth record".

As soon as one adds the pagination macro in your action body, the graphql return type is different, including for these joined reads, which I don't want. Watch...

With offset? true configuration on project.ex:

actions do
  read :read do
    pagination do
      offset? true
    end
  end
end

Then when joining to review.projects with this query:

query listReviews {
  listReviews {
    results {
      projects {
        id
        name
      }
    }
  }
}

Then when joining to review.projects with the same query, graphql introspection shows projects as type PageOfProject!, which is:

{ hasNextPage Boolean!, results [Project!] }

Keyset pagination

Keyset pagination is "get me the n number records after the record with id of abc123".

Changing to keyset? true configuration on project.ex:

actions do
  read :read do
    pagination do
      offset? true
    end
  end
end

Then when joining to review.projects with the same query, graphql introspection shows projects as type ProjectConnection!, which is:

{ edges [ProjectEdge!], pageInfo [PageInfo!] }

And where ProjectEdge is:

{ cursor: String!, node: Project! }

Disabling pagination

I want pagination sometimes but not others. To remove it from this review.projects join, I can add another keyword to the pagination macro, required?:

actions do
  read :read do
    pagination do
      required? false
    end
  end
end

Now, the return type for the same query of review.projects is [!Project!]!, which goes directly to the entity without an intermediate pagination object. This is what I want.

Re-enabling pagination

Let's say we want to go back in the other direction on a per-query basis. If you have a graphql endpoint and want to turn pagination back on:

graphql do
  type :project

  queries do
    list :list_projects, :read, paginate_with: :offset
  end
end

If you have a code interface for read, you can toggle the pagination on/off with the page: keyword:

MyProj.Project.read!(page: true)