apollographql / apollographql/fullstack-tutorial

Launches pagination implementation is a bad example for reference

Offen
#78 1 Kommentar 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
TypeScript
Sterne
1.2k
Forks
808
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

The GraphQL server-side cursor pagination example should be discarded. While the intent of the `paginateResults` function in `final/server/src/utils.js` is good, there are a number of significant flaws with this implementation.

The lowest hanging fruit is that there is a line of code at the end of the function - `results.slice(cursorIndex >= 0 ? cursorIndex + 1 : 0, cursorIndex >= 0);` which is unreachable.

However, the most egregious error is how the `launches` function is defined in `final/server/src/resolvers.js` - which gives the impression that data is being paged responsibly. It is **not**

Every time pagination is invoked, the API request loads ALL THE DATA from the API and then passes it to the pagination function. For the example SpaceX data, there are approximately 76 results that get loaded and then processed to return the 20 results the user is expecting:

```
Query: {
launches: async (_, { pageSize = 20, after }, { dataSources }) => {
const allLaunches = await dataSources.launchAPI.getAllLaunches();
// we want these in reverse chronological order
allLaunches.reverse();

const launches = paginateResults({
after,
pageSize,
results: allLaunches,
});

return {
launches,
cursor: launches.length ? launches[launches.length - 1].cursor : null,
// if the cursor of the end of the paginated results is the same as the
// last item in _all_ results, then there are no more results after this
hasMore: launches.length
? launches[launches.length - 1].cursor !==
allLaunches[allLaunches.length - 1].cursor
: false,
};
},
...
```

If that API endpoint were to return a massive amount of data (imagine 40,000 results), this resolver would load all 40,000 results and then find 20 to return. When the user would click load more, all 40,000 results would be loaded into memory again and then the next 20 results would be returned...effectively processing 80,000 results to display 40 to the user. EEK!

This is definitely something that should be revisited. Imagine a scenario with 30 users following a simple workflow of viewing the first 20 results and then loading an additional 20 results.

Additionally, if the result set grew (imagine 40,001 records), the newest record would never be displayed to the user because it would have been in a spot the cursor presumably has already visited, right?

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Lesen Sie final/server/src/utils.js und final/server/src/resolvers.js und konzentrieren Sie sich auf paginateResults und Query.launches; verfolgen Sie, wie getAllLaunches Daten für jede Anfrage bereitstellt. Definieren Sie das beabsichtigte Paginierungsverhalten und überprüfen Sie, dass die erste und die nachfolgenden Seiten cursor, pageSize, ordering und hasMore-Semantik beibehalten, ohne den vollständigen Ergebnissatz zu laden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
graphql, javascript, node.js
Bereich
backend-api-design, performance
Issue-Typ
Refactoring
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.