> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination de l'API Solana DAS : Interrogation efficace de grands ensembles de données

> Pagination basée sur des pages et par jeux de clés pour l'API Solana DAS. Itérez sur de grands ensembles de données de manière efficace avec des stratégies basées sur des curseurs et des plages ainsi que des requêtes parallèles.

## Aperçu

Les méthodes de l'API DAS renvoient jusqu'à 1 000 enregistrements par appel. Pour en récupérer davantage, vous utilisez la pagination — effectuant plusieurs appels et parcourant des pages de données. Helius prend en charge deux mécanismes : la pagination basée sur des pages et celle par jeux de clés.

La pagination basée sur des pages est le moyen le plus simple pour commencer. La pagination par jeux de clés s'adresse aux utilisateurs avancés interrogeant de grands ensembles de données (500k+) de manière efficace.

## Quand l'utiliser

* **Basée sur des pages** — vues statiques, tableaux de bord et la plupart des requêtes quotidiennes. Simple et intuitive.
* **Jeux de clés (curseur ou plage)** — grands ensembles de données (collections entières, 500k+ actifs) où le parcours par pages devient lent.
* **Jeux de clés parallèles** — l'option la plus rapide pour scanner une collection entière en partitionnant la plage d'adresses.

## Options de tri

Vous pouvez trier les résultats par différents champs en utilisant le champ `sortBy` :

| Valeur          | Trie par                                | Recommandé ? |
| --------------- | --------------------------------------- | ------------ |
| `id`            | ID de l'actif en binaire (par défaut)   | Oui          |
| `created`       | Date de création de l'actif             | Oui          |
| `recent_action` | Date de dernière mise à jour de l'actif | Non          |
| `none`          | Pas de tri                              | Non          |

Désactiver le tri offre les résultats les plus rapides, mais comme les données ne sont pas ordonnées, vous pouvez obtenir des résultats incohérents lors de la pagination.

## Pagination basée sur des pages

Vous spécifiez le numéro de page et le nombre d'éléments par page. Pour passer à la page suivante, incrémentez le numéro de la page. C’est simple, intuitif et rapide pour la plupart des cas d'utilisation.

<Accordion title="Exemple">
  ```javascript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      let page = 1;
      let items = [];
      while (true) {
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: {
                      grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                      page: page,
                      limit: 1000,
                      sortBy: { sortBy: 'id', sortDirection: 'asc' },
                  },
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results from page ${page}`);
              items.push(...result.items);
              page += 1;
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

L'utilisation des pages nécessite que la base de données parcoure tous les éléments jusqu'à ce qu'elle atteigne la page suivante. Par exemple, si vous demandez la page 100 avec une taille de page de 1 000, la base de données doit parcourir les premiers 1 million d'enregistrements avant de retourner vos données. Pour cette raison, la pagination basée sur des pages n'est pas recommandée pour de grands ensembles de données — la pagination par jeux de clés est bien mieux adaptée à ces charges de travail.

## Pagination par jeux de clés

Vous définissez les pages en fournissant des conditions qui filtrent l'ensemble de données. Par exemple, "obtenez tous les actifs avec un ID > X mais un ID \< Y." Vous parcourez l'ensemble du dataset en modifiant X ou Y à chaque appel. Il existe deux méthodes de pagination par jeux de clés :

1. **Basée sur des curseurs** — plus facile à utiliser mais moins flexible.
2. **Basée sur des plages** — plus complexe mais très flexible.

La pagination par jeux de clés n'est prise en charge que lors du tri par `id`.

### Basée sur des curseurs

Une requête DAS sans paramètres de pagination renvoie un curseur. Renvoyez le curseur à l'API DAS pour continuer là où vous vous êtes arrêté.

<Accordion title="Exemple">
  ```typescript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      let items = [];
      let cursor;
      while (true) {
          let params = {
              grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
              limit: 1000,
              sortBy: { sortBy: 'id', sortDirection: 'asc' },
          } as any;
          if (cursor != undefined) {
              params.cursor = cursor;
          }
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: params,
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results for cursor ${cursor}`);
              cursor = result.cursor;
              items.push(...result.items);
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

Au moment de l'écriture, le curseur est le dernier ID d'actif de la réponse ; cependant, la conception du curseur est flexible et peut prendre en charge n'importe quelle chaîne.

### Basée sur des plages

Pour interroger sur une plage, spécifiez `before` et/ou `after`. La requête est essentiellement "obtenez tous les actifs après X mais avant Y." Vous parcourez l'ensemble de données en mettant à jour le paramètre `before` ou `after` à chaque appel.

<Accordion title="Exemple">
  ```javascript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      // Two NFTs from the Tensorian collection.
      // The "start" item has a lower asset ID (in binary) than the "end" item.
      // We will traverse in ascending order.
      let start = '6CeKtAYX5USSvPCQicwFsvN4jQSHNxQuFrX2bimWrNey';
      let end = 'CzTP4fUbdfgKzwE6T94hsYV7NWf1SzuCCsmJ6RP1xsDw';
      let sortDirection = 'asc';
      let after = start;
      let before = end;
      let items = [];

      while (true) {
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: {
                      grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                      limit: 1000,
                      after: after,
                      before: before,
                      sortBy: { sortBy: 'id', sortDirection: sortDirection },
                  },
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results with (after: ${after}, before: ${before})`);
              after = result.items[result.items.length - 1].id;
              items.push(...result.items);
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

## Requête parallèle avec jeux de clés (avancé)

Les utilisateurs avancés interrogeant de grands ensembles de données (par exemple, des collections NFT compressées entières) devraient utiliser la pagination par jeux de clés pour les performances. L'exemple suivant montre comment interroger en parallèle en partitionnant la plage d'adresses Solana et en utilisant les paramètres `before`/`after`. Cette méthode est rapide, efficace et sûre.

<Accordion title="Exemple">
  Dans l'exemple ci-dessous, nous scannons l'ensemble de la collection Tensorian (\~10k enregistrements). Il partitionne l'espace d'adresses Solana en 8 plages et scanne ces plages simultanément. C'est bien plus rapide que les autres approches.

  ```typescript theme={"system"}
  import base58 from 'bs58';

  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const main = async () => {
      let numParitions = 8;
      let partitons = partitionAddressRange(numParitions);
      let promises = [];
      for (const [i, partition] of partitons.entries()) {
          let [s, e] = partition;
          let start = bs58.encode(s);
          let end = bs58.encode(e);
          console.log(`Parition: ${i}, Start: ${start}, End: ${end}`);

          let promise: Promise<number> = new Promise(async (resolve, reject) => {
              let current = start;
              let totalForPartition = 0;
              while (true) {
                  const response = await fetch(url, {
                      method: 'POST',
                      headers: {
                          'Content-Type': 'application/json',
                      },
                      body: JSON.stringify({
                          jsonrpc: '2.0',
                          id: 'my-id',
                          method: 'searchAssets',
                          params: {
                              grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                              limit: 1000,
                              after: current,
                              before: end,
                              sortBy: { sortBy: 'id', sortDirection: 'asc' },
                          },
                      }),
                  });
                  const { result } = await response.json();
                  totalForPartition += result.items.length;
                  console.log(`Found ${totalForPartition} total items in parition ${i}`);
                  if (result.items.length == 0) {
                      break;
                  } else {
                      current = result.items[result.items.length - 1].id;
                  }
              }
              resolve(totalForPartition);
          });
          promises.push(promise);
      }
      let results = await Promise.all(promises);
      let total = results.reduce((a, b) => a + b, 0);
      console.log(`Got ${total} total items`);
  };

  // Function to convert a BigInt to a byte array
  function bigIntToByteArray(bigInt: bigint): Uint8Array {
      const bytes = [];
      let remainder = bigInt;
      while (remainder > 0n) {
          // use 0n for bigint literal
          bytes.unshift(Number(remainder & 0xffn));
          remainder >>= 8n;
      }
      while (bytes.length < 32) bytes.unshift(0); // pad with zeros to get 32 bytes
      return new Uint8Array(bytes);
  }

  function partitionAddressRange(numPartitions: number) {
      let N = BigInt(numPartitions);

      // Largest and smallest Solana addresses in integer form.
      // Solana addresses are 32 byte arrays.
      const start = 0n;
      const end = 2n ** 256n - 1n;

      // Calculate the number of partitions and partition size
      const range = end - start;
      const partitionSize = range / N;

      // Calculate partition ranges
      const partitions: Uint8Array[][] = [];
      for (let i = 0n; i < N; i++) {
          const s = start + i * partitionSize;
          const e = i === N - 1n ? end : s + partitionSize;
          partitions.push([bigIntToByteArray(s), bigIntToByteArray(e)]);
      }

      return partitions;
  }

  main();
  ```
</Accordion>

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Rechercher des actifs" icon="magnifying-glass" href="/docs/fr/das/search">
    Filtrer les actifs par propriétaire, collection et type de jeton.
  </Card>

  <Card title="Obtenir des actifs (NFTs)" icon="image" href="/docs/fr/das/get-nfts">
    Récupérer des NFTs, collections, éditions et preuves.
  </Card>

  <Card title="Référence de l'API DAS" icon="code" href="/docs/fr/api-reference/das">
    Schémas complets pour chaque méthode DAS.
  </Card>
</CardGroup>
