Column.Pagination (Column v1.0.0)

Copy Markdown View Source

Helpers for working with Column's cursor-based pagination.

Column paginates all list endpoints using starting_after / ending_before cursors (mutually exclusive), returning objects in inverse chronological order. Responses always include a has_more boolean.

Automatic streaming

stream/3 wraps any list function into an Elixir.Stream, lazily fetching pages as you consume items:

Column.BankAccounts.list()
|> Column.Pagination.stream(&Column.BankAccounts.list/1, limit: 50)
|> Enum.take(200)

Manual pagination

{:ok, page1} = Column.BankAccounts.list(limit: 10)
if page1["has_more"] do
  last_id = page1["data"] |> List.last() |> Map.get("id")
  {:ok, page2} = Column.BankAccounts.list(limit: 10, starting_after: last_id)
end

Summary

Functions

Builds pagination query params from a keyword list, validating constraints.

Fetches ALL pages for a list function, returning a flat list of all items.

Wraps a Column list function in a lazy Stream, automatically following has_more cursors. Each emitted element is a single resource map.

Types

list_fn()

@type list_fn() :: (keyword() -> {:ok, page()} | {:error, Column.Error.t()})

page()

@type page() :: %{required(String.t()) => [map()] | boolean() | any()}

pagination_param_key()

@type pagination_param_key() :: String.t()

pagination_param_value()

@type pagination_param_value() :: pos_integer() | String.t() | nil

pagination_params()

@type pagination_params() :: %{
  optional(pagination_param_key()) => pagination_param_value()
}

Functions

build_params(opts)

@spec build_params(keyword()) :: {:ok, pagination_params()} | {:error, String.t()}

Builds pagination query params from a keyword list, validating constraints.

fetch_all(list_fn, opts \\ [])

@spec fetch_all(
  list_fn(),
  keyword()
) :: {:ok, [map()]} | {:error, Column.Error.t()}

Fetches ALL pages for a list function, returning a flat list of all items.

stream(list_fn, opts \\ [])

@spec stream(
  list_fn(),
  keyword()
) :: Enumerable.t()

Wraps a Column list function in a lazy Stream, automatically following has_more cursors. Each emitted element is a single resource map.

stream = Column.Pagination.stream(&Column.Entities.list/1, limit: 50)
Enum.each(stream, fn entity -> process(entity) end)