In Carely von unserem Service wird die Serverseite von Ruby (on Rails) implementiert, und der Datenaustausch mit der Front (Vue) wird von graphQL implementiert. Bei der Paginierung in Schienen wird häufig ein Juwel namens Kaminari verwendet. Bei graphQL scheint die Cursor-Paginierung im Relay-Stil Standard zu sein, daher habe ich beide Implementierungsmethoden ausprobiert.
kaminari ist Version 1.2.1 graphql-ruby ist Version 1.10.10 ist.
(Dies ist die URL zur Erläuterung der Paginierung von graphql-ruby) https://graphql-ruby.org/pagination/using_connections.html
Beschreiben Sie die Schema-Klasse für die Verwendung des Paginierungs-Plugins wie unten gezeigt.
class MySchema < GraphQL::Schema
.
.
use GraphQL::Pagination::Connections
.
end
Verwenden Sie die Beschreibung :: connection_type
, um die Abfrage zu definieren, zu der Sie die Paginierungsfunktion hinzufügen möchten.
field :users, Types::UserType::connection_type, null: true do
.
.
argument :name, String, "Name", required: false
.
end
Das ist alles für die serverseitige Implementierung.
Sie können jetzt die Parameter für "first (last), after (before)" angeben. Mit der folgenden Abfrage werden 10 Elemente von zuerst und 10 Elemente von nachher durch Angabe von nachher erfasst. Geben Sie für die nachfolgend angegebene Zeichenfolge die vom Cursor erhaltene Zeichenfolge an. Es kann auch ein Feld mit dem Namen "pageInfo" angegeben werden. Gibt es eine vorherige oder eine nächste Seite? Sie können die Position der Start- und Endcursor ermitteln.
query MyQuery {
users (first: 10, after: "xxxx") {
pageInfo {
hasPreviousPage
hasNextPage
endCursor
startCursor
}
edges {
cursor
node {
firstName
lastName
mailAddress
age
.
.
}
}
##Kann mit Knoten genommen werden
nodes {
firstName
lastName
mailAddress
age
.
.
}
##Beispiel Ergebnis
{
"data": {
"users": {
"pageInfo": {
"hasPreviousPage": false,
"hasNextPage": true,
"endCursor": "MTA",
"startCursor": "MQ"
},
"edges": [
{
"cursor": "MQ",
"node": {
"firstName": "Hogehoge",
"lastName": "Fuga Fuga",
"mailAddress": "[email protected]",
"age": "20"
}
},
{
"cursor": "Mg",
"node": {
"firstName": "Hogehoge 2",
"lastName": "Fuga Fuga 2",
"mailAddress": "[email protected]",
"age": "30"
}
},
.
.
],
"nodes": [
{
"firstName": "Hogehoge",
"lastName": "Fuga Fuga",
"mailAddress": "[email protected]",
"age": "20"
},
{
"firstName": "Hogehoge 2",
"lastName": "Fuga Fuga 2",
"mailAddress": "[email protected]",
"age": "30"
},
.
.
]
Die allgemeinen Methoden für die Paginierung in Kaminari sind wie folgt.
#Teilen Sie die erste Seite alle 10
User.page(1).per(10)
#Gesamtzahl
User.page(1).per(10).total_count
#Anzahl der Tolal-Seiten
User.page(1).total_pages
#Anzahl der Seiten pro Seite
User.page(1).limit_value
#Aktuelle Anzahl der Seiten
User.page(1).current_page
#Nächste Seitenzahl
User.page(1).next_page
#Anzahl der vorherigen Seiten
User.page(1).prev_page
#Ob es die erste Seite ist
User.page(1).first_page?
#Ob es die letzte Seite ist
User.page(1).last_page?
Erstellen Sie einen Typ für die Paginierung wie unten gezeigt.
module Types
class PaginationType < Types::BaseObject
field :total_count, Int, null: true
field :limit_value, Int, null: true
field :total_pages, Int, null: true
field :current_page, Int, null: true
end
end
Erstellen Sie einen "UserType" und einen "UsersType", die mehrere Benutzerinformationen und eine Paginierung wie folgt zurückgeben:
module Types
class UserType < Types::BaseObject
field :uuid, String, null: true
field :first_name, String, null: true
field :last_name, String, null: true
field :mail_address, String, null: true
field :age, String, null: true
.
.
end
end
module Types
class UsersType < Types::BaseObject
field :pagination, PaginationType, null: true
field :users, [UserType], null: true
end
end
Fügen Sie der Abfrage die folgende Verarbeitung hinzu, um Paginierungsinformationen zurückzugeben.
#Seite mit Argument,Hinzugefügt, um per bestehen zu können
field :users, Types::UserType, null: true do
.
.
argument :name, String, "Name", required: false
argument :page, Int, required: false
argument :per, Int, required: false
.
end
#Verwenden Sie die Paginierung von kaminari, wenn es Argumente Seite und per gibt
def users(**args)
.
.
users = User.page(args[:page]).per(args[:per])
{
users: users,
pagination: pagination(users)
}
end
#Gibt die Nummer nach der Kaminari-Methode zurück
def pagination(result)
{
total_count: result.total_count,
limit_value: result.limit_value,
total_pages: result.total_pages,
current_page: result.current_page
}
end
Dies ist ein Beispiel für eine Abfrage, bei der die erste Seite, die in 10 Fälle unterteilt ist, und das Ergebnis abgerufen werden.
query MyQuery {
users (per:10, page:1) {
pagination {
currentPage
limitValue
totalCount
totalPages
}
users {
firstName
lastName
mailAddress
age
.
.
}
}
##Beispiel Ergebnis
{
"data": {
"users": {
"pagination": {
"currentPage": 1,
"limitValue": 10,
"totalCount": 100,
"totalPages": 10
},
"users": [
{
"firstName": "Hogehoge",
"lastName": "Fuga Fuga",
"mailAddress": "[email protected]",
"age": "20"
},
{
"firstName": "Hogehoge 2",
"lastName": "Fuga Fuga 2",
"mailAddress": "[email protected]",
"age": "30"
},
.
.
]
Relay-Style Cursor Pagination
Es sieht gut aus, weil es einfach zu bedienen ist, wenn Sie nur mit der API nach Informationen suchen.
Wenn Sie eine Benutzeroberfläche erstellen möchten, die die Gesamtzahl der Fälle und die Gesamtzahl der Seiten auf der Vorderseite anzeigt, da sie nur die Standortinformationen per Cursor enthält, Benutzerdefiniert ) Scheint eine "Verbindung" herstellen zu müssen.
kaminari
Wenn Sie nur interne Ingenieure verwenden und eine Benutzeroberfläche erstellen, die die Gesamtzahl der Fälle und die Gesamtzahl der Seiten auf der Vorderseite anzeigt, ist die Verwendung von Kaminari weniger arbeitsintensiv.
Persönlich denke ich, dass es besser wäre, eine benutzerdefinierte Verbindung mit "Relay-Style Cursor Pagination" zu erstellen, da dies dem Stil von graphQL entspricht.