Cursor-based pagination helpers for Solaris API list endpoints.
Solaris uses cursor pagination. Paginated responses include a meta object
with next_page and previous_page cursor strings.
Usage
# Single page
{:ok, body} = Solaris.Onboarding.Persons.list(per_page: 25)
page = Solaris.Pagination.from_response(body)
IO.inspect(page.data) # list of persons
IO.inspect(page.next_cursor) # nil or cursor string
# Lazy stream of all items across all pages
Solaris.Pagination.stream(fn cursor ->
Solaris.Onboarding.Persons.list(after: cursor, per_page: 100)
|> case do
{:ok, body} -> {:ok, Solaris.Pagination.from_response(body)}
err -> err
end
end)
|> Stream.each(&process/1)
|> Stream.run()
# Collect all into memory
{:ok, all} = Solaris.Pagination.all(fn cursor ->
Solaris.Onboarding.Persons.list(after: cursor)
|> case do
{:ok, body} -> {:ok, Solaris.Pagination.from_response(body)}
err -> err
end
end)
Summary
Types
@type page_opts() :: [ page: pos_integer(), per_page: pos_integer(), after: String.t() | nil, before: String.t() | nil ]
Functions
Fetches all pages and returns all items in a single list.
Uses stream/1 internally. For large datasets, prefer stream/1 to avoid
loading everything into memory at once.
Parses a raw Solaris paginated response body into a %Solaris.Pagination{} struct.
Accepts the decoded JSON body map. Falls back gracefully if the response is a plain list (some endpoints skip the wrapper).
@spec stream((String.t() | nil -> {:ok, t()} | {:error, term()})) :: Enumerable.t()
Returns a lazy Stream that auto-paginates through all results.
fetch_fn receives a cursor (nil for the first page) and must return
{:ok, %Solaris.Pagination{}} or {:error, reason}.
The stream halts automatically when next_cursor is nil.
Raises on fetch errors to surface them through Stream.run/1 or Enum.to_list/1.
Converts page options into query parameters for a Solaris list request.
Filters out nil values automatically.
Examples
Pagination.to_query(page: 2, per_page: 50)
# => [page: 2, per_page: 50]
Pagination.to_query(after: "cursor_abc", per_page: 100, before: nil)
# => [after: "cursor_abc", per_page: 100]