Dans Carely, notre service, le côté serveur est implémenté en Ruby (on Rails), et l'échange de données avec le front (Vue) est implémenté en graphQL. La pagination dans Rails utilise souvent une gemme appelée Kaminari, mais dans le cas de graphQL, la pagination du curseur de style relais semble être standard, j'ai donc essayé les deux méthodes d'implémentation.
kaminari est la version 1.2.1 graphql-ruby est la version 1.10.10 est.
(Ceci est l'URL pour expliquer la pagination de graphql-ruby) https://graphql-ruby.org/pagination/using_connections.html
Décrivez la classe de schéma pour utiliser le plugin de pagination comme indiqué ci-dessous.
class MySchema < GraphQL::Schema
.
.
use GraphQL::Pagination::Connections
.
end
Utilisez la description :: connection_type
pour définir la requête à laquelle vous souhaitez ajouter la fonctionnalité de pagination.
field :users, Types::UserType::connection_type, null: true do
.
.
argument :name, String, "Nom", required: false
.
end
C'est tout pour l'implémentation côté serveur.
Vous pouvez maintenant spécifier les paramètres pour premier (dernier), après (avant)
.
Avec la requête ci-dessous, 10 éléments seront acquis à partir du premier et 10 éléments seront acquis par après en spécifiant après.
Pour la chaîne de caractères spécifiée dans after, spécifiez la chaîne de caractères obtenue par le curseur.
De plus, un champ appelé «pageInfo» peut être spécifié, et y a-t-il une page précédente ou une page suivante? Vous pouvez obtenir la position des curseurs de début et de fin.
query MyQuery {
users (first: 10, after: "xxxx") {
pageInfo {
hasPreviousPage
hasNextPage
endCursor
startCursor
}
edges {
cursor
node {
firstName
lastName
mailAddress
age
.
.
}
}
##Peut être pris avec des nœuds
nodes {
firstName
lastName
mailAddress
age
.
.
}
##Exemple de résultat
{
"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"
},
.
.
]
Les méthodes générales utilisées pour la pagination en kaminari sont les suivantes.
#Obtenez la première page divisée tous les 10
User.page(1).per(10)
#nombre total
User.page(1).per(10).total_count
#nombre de pages tolal
User.page(1).total_pages
#Nombre de pages par page
User.page(1).limit_value
#Nombre actuel de pages
User.page(1).current_page
#Nombre de pages suivantes
User.page(1).next_page
#Nombre de pages précédentes
User.page(1).prev_page
#Que ce soit la première page
User.page(1).first_page?
#Que ce soit la dernière page
User.page(1).last_page?
Créez un type pour la pagination comme indiqué ci-dessous.
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
Créez un ʻUserType et un ʻUsersType
qui renvoie plusieurs informations utilisateur et une pagination comme suit:
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
Ajoutez le traitement suivant à Query pour renvoyer les informations de pagination.
#Page avec argument,Ajouté pour pouvoir passer par
field :users, Types::UserType, null: true do
.
.
argument :name, String, "Nom", required: false
argument :page, Int, required: false
argument :per, Int, required: false
.
end
#Utilisez la pagination de kaminari s'il y a une page d'arguments et par
def users(**args)
.
.
users = User.page(args[:page]).per(args[:per])
{
users: users,
pagination: pagination(users)
}
end
#Renvoie le nombre en utilisant la méthode de Kaminari
def pagination(result)
{
total_count: result.total_count,
limit_value: result.limit_value,
total_pages: result.total_pages,
current_page: result.current_page
}
end
Voici un exemple de requête qui récupère la première page divisée en 10 cas et le résultat.
query MyQuery {
users (per:10, page:1) {
pagination {
currentPage
limitValue
totalCount
totalPages
}
users {
firstName
lastName
mailAddress
age
.
.
}
}
##Exemple de résultat
{
"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
Cela a l'air bien car il est facile à utiliser si vous recherchez simplement des informations avec l'API.
Si vous souhaitez créer une interface utilisateur qui affiche le nombre total de cas et le nombre total de pages au recto car elle ne contient que les informations de localisation par curseur, Personnalisé ) Semble avoir besoin de créer une connexion
.
kaminari
Si vous n'utilisez que des ingénieurs internes et créez une interface utilisateur qui affiche le nombre total de cas et le nombre total de pages au recto, l'utilisation de kaminari demande moins de travail.
Personnellement, je pense qu'il serait préférable de créer une connexion personnalisée en utilisant Relay-Style Cursor Pagination
car cela convient au style de graphQL.
Recommended Posts