2016-05-03 8 views
1

GraphQL und Relay verfügt über einen robusten Paginierungsalgorithmus, der eine einfache Paginierung für den Endbenutzer ermöglicht und die Paginierung sogar in unbegrenzten und auftragsunabhängigen Ergebnissen ermöglicht.Warum gibt es kein Argument "Position" in Relay + GraphQL-Verbindungen?

Allerdings habe ich einen Anwendungsfall, dass ich nicht wirklich sicher bin, wie über das Tun in GraphQL und Relais zu gehen, und es ist ganz einfach, dass ich bin sicher, dass ich gerade etwas verpaßt.

Wie kann ich zum Beispiel erhalten die fünfte Element (und nur das fünfte Element), wenn meine Liste bestellt wird (von, sagen wir, ein orderBy Argument)?

Antwort

1

Das ist nicht sehr gut dokumentiert, aber hier ist, wie es geht.

query { 
    allPeople(first: 5, last: 1) { 
    edges { 
     node { 
     name 
     } 
    } 
    } 
} 

Zuerst first: 5 wählen Sie die ersten 5 Personen in der Liste zu bekommen. Dann tun Sie last:1, die die letzte Person von dieser Untergruppe erhält. Mit anderen Worten - nimm die fünfte Person.

Wenn Sie (first: 5, last: 2) tun würden Sie den 4. bekommen und die fünfte Person in der Liste.

Demo (wenn es einen Fehler zurückgibt - manuell neu geben Sie das Wort query in der Abfrage und es wird funktionieren). Dann versuchen Sie es erneut ohne first und last, um die ganze Liste zu sehen, und Sie werden sehen, dass Leia 5. ist.

+0

Obwohl dies wie ein bisschen wie ein Hack klingen mag, definiert die Verbindungsspezifikation in ihrer aktuellen Form [definiert dieses Verhalten explizit] (http://facebook.github.io/relay/graphql/connections.htm). Dies ist etwas nachsichtiger als die ursprüngliche (interne) GraphQL-Implementierung von Facebook, die die Verwendung von "first" und "last" zusammen als ungültig zurückweist. – wincent

+0

@ Wincent, ich folge nicht. Können Sie erklären? Der Link zeigt, wie es geht, wenn Sie einen Cursor haben. OP möchte den N-ten Punkt ohne einen Cursor holen. – Chris

+0

Schauen Sie in Abschnitt 4.3: es beschreibt das Verhalten sowohl mit als auch ohne Cursor. Sagt auch: "Es wird dringend davon abgeraten, einen Wert für" first "und" last "zu verwenden, da dies zu verwirrenden Abfragen und Ergebnissen führen kann." also Vorbehalt emptor ... – wincent

1

Wenn Sie eine geordnete Liste im Backend haben und Sie das Element an einer bestimmten Position zu erhalten, geben Sie einfach den Positionswert als Argument für das Abfragefeld. Der Code für das Abfragefeld sieht wie folgt aus:

employee: { 
    type: EmployeeType, 
    args: { 
    position: { 
     type: new GraphQLNonNull(GraphQLInt) 
    }, 
    ...args, 
    }, 
    resolve: async (context, {position, ...args}) => { 
    // Get the ordered list of employees, probably from cache. 
    // Pick the employee with the requested position in the list. 
    // Return the employee. 
    }, 
}, 
+2

Dies ist auch eine legitime Vorgehensweise. Ein ähnliches, übliches Muster besteht darin, ein "Finde" -Argument zum Auswählen eines einzelnen Elements aus einer Verbindung zu erstellen. Beachten Sie auch, dass sowohl Cursor als auch IDs undurchsichtig sind. Sie können also alle gewünschten Verhaltensweisen und internen Implementierungsdetails definieren und sie dann verwenden/missbrauchen. Wenn Sie beispielsweise ein Limit-/Offset-basiertes Paginierungsmodell implementieren möchten, können Sie den Offset so in den Cursor einbetten, dass Sie "first: 1 after: $ cursor" -Typ-Abfragen ausführen und den entsprechenden Cursor spontan generieren können , dies bricht die Kapselung, also sparsam verwenden). – wincent