GraphqlOffsetBackend
Manage GraphQL interactions with a server that uses offset pagination instead of cursor-based pagination.
- Overview
- graphql_client
- graphql_client_name
- root_field
- api_case
- model_case
- is_collection
- max_relationship_depth
- relationship_limit
- use_connection_for_relationships
- can_create
- can_update
- can_delete
- 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.