Paginação

Uma API que retorna uma lista de resultados pode oferecer diferentes maneiras para paginar seu retorno. Em casos com poucos resultados a paginação pode não ser necessária, contudo, conforme esse número aumenta, fica mais clara a necessidade de uma maneira eficiente de paginação, tanto para melhorar a navegação entre os resultados quanto para ressaltar o que será mostrado.

No Storefront API dois tipos de paginação são possíveis: Offset _e _Cursor.

Paginação por Offset

A paginação por offset tem como principal vantagem a navegação livre por diferentes números de páginas. É possível sair da primeira para a última página, ou então da primeira direto para a quinta, por exemplo. Contudo, essa paginação pode sofrer com problemas de performance conforme o número total de resultados aumenta, visto que em qualquer requisição todos os dados são buscados, mas somente uma parcela é utilizada, sendo os demais resultados descartados.

Parâmetros de entrada

ParâmetroTipoDescrição
limitintO número de resultados a retornar
offsetintO número de resultados a pular

Objeto de retorno

CampoTipoDescrição
items[Entidade]Lista das entidades
totalCountint!O número total de resultados em todas as páginas
pageint!O número atual da página baseado nos parâmetros de entrada

📘

As queries que suportam esse tipo de paginação são as de search e hotsite. Nessas queries é possível utilizar o campo productsByOffset para retornar os produtos.

🚧

Referente a paginação: por questões de performance, só é possível paginar até 10 mil produtos. Caso esse limite seja ultrapassado no hotsite, recomendamos que seja feita a "quebra" em hotsites mais específicos.

Exemplo

Busca por "tênis" retornando informações de 2 produtos:

query {
  search(query:"tenis") {
    productsByOffset(limit:2) {
      totalCount
      page
      items {       
        productVariantId
        productId
        productName
      }      
    }
  }
}
Mostrar resposta
{
  "data": {
    "search": {
      "productsByOffset": {
        "totalCount": 68,
        "page": 1,
        "items": [
          {
            "productVariantId": 372467,
            "productId": 175349,
            "productName": "Tênis Modare Casual 7339.200.19046.52531"
          },
          {
            "productVariantId": 372375,
            "productId": 175336,
            "productName": "Tênis Olympikus Like Feminino 43499798"
          }
        ]
      }
    }
  }
}

Paginação por Cursor

A paginação por cursor é a mais utilizada em APIs GraphQL, pois não sofre com os possíveis problemas de performance de gerados pela paginação por offset. Porém, sua principal desvantagem é não oferecer a navegação livre entre as páginas. Em uma navegação por cursor só é possível se movimentar para uma página de resultados adjacente com a atual, ou seja, a próxima ou a anterior. Esta limitação se deve ao uso de cursores, que definem o início e o fim de cada página.

Nesse tipo de paginação uma entidade sempre está associada a um cursor, que é utilizado como referência para buscar os próximos resultados.

Parâmetros de entrada

ParâmetroTipoDescrição
firstintO número de resultados a retornar. Utilizado ao paginar resultados seguintes.
lastintO número de resultados a retornar. Utilizado ao paginar resultados anteriores.
afterstringO valor do cursor para utilizar como referência. Utilizado ao paginar resultados seguintes.
beforestringO valor do cursor para utilizar como referência. Utilizado ao paginar resultados anteriores.

❗️

O parâmetro first é o único que pode ser enviado sozinho. O parâmetro after depende do first e o parâmetro before depende do last. Qualquer outra combinação destes parâmetros gera um erro na requisição.

Objeto de retorno

CampoTipoDescrição
edges[EntidadeEdge!]Lista que contém informações da entidade e seu cursor.
edges.cursorstring!O cursor relacionado a essa entidade.
edges.nodeEntidadeA entidade.
totalCountint!O número total de resultados
pageInfoPageInfo!Objeto com informações para a paginação
nodes[Entidade]Lista das entidades sem o cursor associado

📘

Todas as queries e campos que possuem paginação por cursor retornam uma entidade com Connection no nome. É um padrão do GraphQL que adiciona os campos acima automaticamente no objeto de retorno.

Exemplo

Busca por "tênis" retornando informações dos 2 primeiros produtos:

query {
  search(query:"tenis") {
    products(first:2) {
      totalCount
      pageInfo {
        hasNextPage
        hasPreviousPage
        startCursor
        endCursor
      }
      edges {
        cursor
        node {
          productVariantId
          productId
          productName
        }
      }      
    }
  }
}
Mostrar resposta
{
  "data": {
    "search": {
      "products": {
        "totalCount": 68,
        "pageInfo": {
          "hasNextPage": true,
          "hasPreviousPage": false,
          "startCursor": "eyJPZmZzZXQiOjF9",
          "endCursor": "eyJPZmZzZXQiOjJ9"
        },
        "edges": [
          {
            "cursor": "eyJPZmZzZXQiOjF9",
            "node": {
              "productVariantId": 372467,
              "productId": 175349,
              "productName": "Tênis Modare Casual 7339.200.19046.52531"
            }
          },
          {
            "cursor": "eyJPZmZzZXQiOjJ9",
            "node": {
              "productVariantId": 372375,
              "productId": 175336,
              "productName": "Tênis Olympikus Like Feminino 43499798"
            }
          }
        ]
      }
    }
  }
}