Skip to main content

Paginazione GraphQL

Le liste GraphQL sono paginate a cursore: inserimenti e cancellazioni durante la navigazione non spostano le pagine.

Struttura della risposta

Ogni query paginata restituisce una Connection:

type Connection {
  pageInfo: PageInfo!
  edges: [Edge!]!
}

type Edge {
  cursor: String!
  node: <TipoEntità>!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
  total: Int!
}

total è il numero complessivo dei risultati, indipendente dalla paginazione.

Input di paginazione

input PaginationInput {
  first: Int   # quanti elementi prendere dalla testa
  last:  Int   # quanti elementi prendere dalla coda
  after: String  # cursore: prendi gli elementi dopo questo
  before: String # cursore: prendi gli elementi prima di questo
}

Senza first né last la pagina è di 25 elementi. first e last non si possono usare insieme.

Navigazione in avanti (forward)

Usa first e after.

Prima pagina:

query {
  donations(pagination: { first: 20 }) {
    pageInfo {
      hasNextPage
      endCursor
      total
    }
    edges {
      cursor
      node {
        id
        state
        amount
      }
    }
  }
}

Pagina successiva, con l'endCursor della risposta precedente:

query {
  donations(pagination: { first: 20, after: "Y3Vyc29yOnYxOjIwMjMtMDgtMTd8MTIz" }) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        state
        amount
      }
    }
  }
}

Navigazione all'indietro (backward)

Usa last e before.

query {
  donations(pagination: { last: 20, before: "Y3Vyc29yOnYxOjIwMjMtMDgtMTd8MTIz" }) {
    pageInfo {
      hasPreviousPage
      startCursor
    }
    edges {
      node {
        id
        state
        amount
      }
    }
  }
}

Come funzionano i cursori

I cursori sono stringhe Base64 che codificano i campi di ordinamento dell'elemento (per esempio payment_date|id). Non costruirli a mano: usa quelli restituiti in startCursor, endCursor o edges[*].cursor.

Recuperare tutti gli elementi

Itera su hasNextPage ed endCursor:

async function fetchAll(client) {
  let after = null;
  const results = [];

  do {
    const { data } = await client.query({
      query: DONATIONS_QUERY,
      variables: { pagination: { first: 100, after } },
    });

    results.push(...data.donations.edges.map(e => e.node));
    after = data.donations.pageInfo.hasNextPage
      ? data.donations.pageInfo.endCursor
      : null;
  } while (after);

  return results;
}

Query che supportano la paginazione

Accettano pagination: PaginationInput:

  • donations
  • payments
  • supporters
  • campaigns
  • checkouts
  • activities

Fonte: https://dev.riseact.org/docs/apis/graphql-pagination. Copia automatica da dev.riseact.org: non modificare qui, le modifiche vanno fatte sulla documentazione Docusaurus.