Skip to content

Mutations API Reference

CASCADE Field Selection

Overview

The cascade field is available on Success types when enable_cascade=True is set on the mutation decorator.

CASCADE is only included in responses when explicitly requested in the GraphQL selection set.

Default Behavior

Important: CASCADE is opt-in at two levels:

  1. Mutation Level (Python decorator):
  2. Default: enable_cascade=False - CASCADE disabled entirely
  3. Explicit: enable_cascade=True - CASCADE tracking enabled

  4. Query Level (GraphQL selection):

  5. Default: No cascade field selected = No CASCADE in response
  6. Explicit: Request cascade { ... } = CASCADE data returned

Examples:

# Default: CASCADE disabled
@mutation
class UpdatePreference:
    # No cascade field available in Success type
    ...

# Explicit: CASCADE enabled
@mutation(enable_cascade=True)
class CreatePost:
    # cascade field available in Success type
    ...
# Query without CASCADE selection
mutation {
  createPost(input: {...}) {
    ... on CreatePostSuccess {
      post { id }
      # No cascade field - not returned even if enable_cascade=True
    }
  }
}

# Query with CASCADE selection
mutation {
  createPost(input: {...}) {
    ... on CreatePostSuccess {
      post { id }
      cascade { updated { __typename id } }  # CASCADE returned
    }
  }
}

Performance Impact:

  • enable_cascade=False: Zero overhead (default for most mutations)
  • enable_cascade=True + no selection: ~5-10% overhead (tracking but not serializing)
  • enable_cascade=True + with selection: ~10-20% overhead (full tracking + serialization)

Best Practice: Only use enable_cascade=True on mutations with side effects that affect multiple entities.

Schema Definition

type Cascade {
  updated: [CascadeEntity!]!
  deleted: [CascadeEntity!]!
  invalidations: [CascadeInvalidation!]!
  metadata: CascadeMetadata!
}

type CascadeEntity {
  __typename: String!
  id: ID!
  operation: String!
  entity: JSON!
}

type CascadeInvalidation {
  queryName: String!
  strategy: String!
  scope: String!
}

type CascadeMetadata {
  timestamp: String!
  affectedCount: Int!
  depth: Int!
  transactionId: String
}

Selection Examples

Full CASCADE:

cascade {
  updated {
    __typename
    id
    operation
    entity
  }
  deleted {
    __typename
    id
  }
  invalidations {
    queryName
    strategy
    scope
  }
  metadata {
    timestamp
    affectedCount
    depth
    transactionId
  }
}

Partial CASCADE (metadata only):

cascade {
  metadata {
    affectedCount
  }
}

With Inline Fragments:

cascade {
  updated {
    __typename
    id
    operation
    entity {
      ... on Post {
        id
        title
      }
      ... on User {
        id
        name
      }
    }
  }
}

Nullability

The cascade field is nullable:

  • Returns null if no side effects occurred
  • Not present in response if not requested in selection
  • Returns object with requested fields if side effects occurred

Performance Characteristics

Selection Payload Overhead Use Case
Not requested 0 bytes Display-only mutations
metadata only ~50-100 bytes Count tracking
invalidations only ~100-300 bytes Cache clearing
updated only ~500-2000 bytes Entity sync
Full CASCADE ~1000-5000 bytes Complete sync