GraphqlOffsetBackend

Manage GraphQL interactions with a server that uses offset pagination instead of cursor-based pagination.

  1. Overview
  2. graphql_client
  3. graphql_client_name
  4. root_field
  5. api_case
  6. model_case
  7. is_collection
  8. max_relationship_depth
  9. relationship_limit
  10. use_connection_for_relationships
  11. can_create
  12. can_update
  13. can_delete
  14. can_query

Overview

Consider the following basic application:

#!/usr/bin/env python3

import clearskies

shared_backend = clearskies.backends.GraphqlOffsetBackend(
    graphql_client=clearskies.clients.GraphqlClient(
        endpoint="https://example.net/gql",
        authentication=clearskies.authentication.Public(),
    )
)


class Product(clearskies.Model):
    id_column_name = "id"
    backend = shared_backend

    id = clearskies.columns.String()
    name = clearskies.columns.String()
    description = clearskies.columns.String()
    price = clearskies.columns.Float()
    created_at = clearskies.columns.Datetime()


cli = clearskies.contexts.Cli(
    lambda products: [product.id for product in products.limit(20)], classes=[Product]
)
cli()

It would generate the following query:

query GetRecords($limit: Int) {
    products(limit: $limit) {
        createdAt description id name price
    }
}

with the following variables:

{"limit": 20}

It does not ask for any pagination data. Instead, it calculates whether or not there is a next page based on the number of records returned.

Otherwise, this backend acts identically to the default GraphqlBackend.

graphql_client

Optional

The GraphQL client instance used to execute queries.

An instance of clearskies.clients.GraphqlClient that handles the connection to your GraphQL API. This is required for the backend to function. Example:

import clearskies

class Project(clearskies.Model):
    id_column_name = "id"
    backend = clearskies.backends.GraphqlBackend(
        graphql_client=clearskies.clients.GraphqlClient(
            endpoint="https://api.example.com/graphql",
            authentication=clearskies.authentication.SecretBearer(
                environment_key="API_TOKEN"
            )
        ),
        root_field="projects"
    )
    id = clearskies.columns.String()
    name = clearskies.columns.String()

graphql_client_name

Optional

The name of the GraphQL client in the DI container.

If you don’t provide a graphql_client directly, the backend will look for a client registered in the dependency injection container with this name. Defaults to “graphql_client”.

root_field

Optional

Dynamically build a GraphQL mutation.

Args:
    operation: "create", "update", or "delete"
    model: The clearskies Model
    data: Data to mutate
    id: Record ID (for update/delete)

Returns: (mutation_string, variables_dict)

api_case

Optional

The case convention used by the GraphQL API for field names.

Allowed values: “camelCase”, “snake_case”, “TitleCase” Defaults to “camelCase” which is the GraphQL standard.

model_case

Optional

The case convention used by clearskies model column names.

Allowed values: “snake_case”, “camelCase”, “TitleCase” Defaults to “snake_case” which is the Python/clearskies standard.

is_collection

Optional

Explicitly set whether the resource is a collection or singular.

Values:

  • None: Auto-detect based on field name patterns (default)
  • True: Resource is a collection (returns multiple items with pagination)
  • False: Resource is singular (returns a single object, like “currentUser”)

Auto-detection works for most cases, but you can override it if needed.

max_relationship_depth

Optional

Maximum depth for nested relationship queries.

Controls how deep the backend will traverse relationships when building GraphQL queries. For example, with max_relationship_depth=2:

  • Depth 0: Root model (Group)
  • Depth 1: First level relationships (Group.projects)
  • Depth 2: Second level relationships (Project.namespace)

This prevents infinite recursion in circular relationships. Defaults to 2.

relationship_limit

Optional

Default limit for HasMany and ManyToMany relationship collections.

When fetching related collections (e.g., projects for a group), this sets the maximum number of related records to fetch. Defaults to 10.

Example:

backend = clearskies.backends.GraphqlBackend(
    graphql_client=my_client,
    relationship_limit=50  # Fetch up to 50 related items
)

use_connection_for_relationships

Optional

Whether to use GraphQL connection pattern for relationship collections.

When True, relationship queries use the connection pattern:

projects(first: 10) {
    nodes { id name }
    pageInfo { endCursor hasNextPage }
}

When False, expects direct arrays:

projects { id name }

Defaults to True (Relay-style connections are the GraphQL standard).

can_create

Optional

Whether creating new records is allowed for this backend.

When set to False, any attempt to create a record will raise a ValueError. This can be set as a class attribute or passed to the constructor.

can_update

Optional

Whether updating existing records is allowed for this backend.

When set to False, any attempt to update a record will raise a ValueError. This can be set as a class attribute or passed to the constructor.

can_delete

Optional

Whether deleting records is allowed for this backend.

When set to False, any attempt to delete a record will raise a ValueError. This can be set as a class attribute or passed to the constructor.

can_query

Optional

Whether querying/reading records is allowed for this backend.

When set to False, any attempt to query records (via iteration, count, find, etc.) will raise a ValueError. This can be set as a class attribute or passed to the constructor.