Skip to content

v3: return pagination metadata from admin listUsers #1602

Description

@spydon

Summary

GoTrueAdminApi.listUsers({int? page, int? perPage}) currently returns a bare Future<List<User>>. It accepts pagination inputs but discards the pagination metadata the server returns (total, nextPage, lastPage, and aud, derived from the Link and X-Total-Count response headers). Callers therefore cannot tell how many users or pages exist, or whether there is a next page, without probing until a short page comes back.

supabase-js exposes this metadata alongside the users. Bringing Dart to parity means changing the return type, which is breaking, so it is scheduled for v3.

Idiomatic Dart shape

Do not mirror supabase-js's { data, error } wrapper. Dart gotrue throws on error, so the response type should carry only the successful payload plus the pagination metadata, matching the existing named-response-class convention (AuthMFAEnrollResponse, UserResponse, etc.):

class ListUsersResponse {
  const ListUsersResponse({
    required this.users,
    this.total,
    this.nextPage,
    this.lastPage,
    this.aud,
  });

  final List<User> users;

  /// Total number of users, from the `X-Total-Count` header.
  final int? total;

  /// Next page number, or null if this is the last page. From the `Link` header.
  final int? nextPage;

  /// Last page number. From the `Link` header.
  final int? lastPage;

  final String? aud;
}
Future<ListUsersResponse> listUsers({int? page, int? perPage});

Parse nextPage / lastPage from the Link header and total from X-Total-Count, so callers can paginate deterministically:

final response = await admin.listUsers(perPage: 50);
for (final user in response.users) { /* ... */ }
if (response.nextPage != null) {
  final next = await admin.listUsers(page: response.nextPage, perPage: 50);
}

Why breaking

The return type changes from List<User> to ListUsersResponse; existing callers that treat the result as a list break. Hence v3.

Follow-up

Reconcile auth.admin.list_users in sdk-compliance.yaml to implemented when this lands.

Context

Part of the SDK parity effort. Tracked under the v3 umbrella (#1278).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions