Déployer un serveur graphql en utilisant des composants en PHP
L du pop, qui utilise le composant comme structure de données plutôt que comme graphique. Le nom de ce serveur provient du pool de construction de composants PHP sur lequel il est basé. (je suis l’auteur de ces deux projets.)
Cet article est divisé en cinq Parties pour expliquer ce qu’est un composant comment un POP fonctionne comment définir un composant dans un POP comment les composants sont naturellement adaptés à la performance de graphql pour résoudre les requêtes graphql en utilisant des composants. 1. Qu’est – ce qu’un composant? Vous pouvez utiliser des composants pour représenter la disposition de chaque page Web. Les composants ne sont qu’un ensemble de codes (comme HTML, Javascript et CSS) combinés pour créer une entité autonome qui peut envelopper d’autres composants pour créer des structures plus complexes ou qui peut être encapsulée par d’autres composants. Chaque composant a un but qui peut être très simple, comme un lien ou un bouton, ou très complexe, comme un carrousel ou un chargeur d’image glisser – déposer.
Construire un site à partir de composants est comme jouer au golf. Par exemple, dans la page suivante, des composants simples (liens, boutons, avatars) sont combinés pour créer des structures plus complexes (widgets, sections, barres latérales, menus) jusqu’à ce que vous obteniez la page:
Dans les sections suivantes, les termes « composant » et « module » sont utilisés de façon interchangeable. Emballage hiérarchique des composants
« du module supérieur au dernier niveau, on s’appelle la hiérarchie des composants. Cette relation peut être représentée par un tableau associatif côté serveur (Key = > attribut Array) dans lequel chaque module déclare son nom comme attribut clé et son module interne sous l’attribut \
La hiérarchie des composants est similaire à: $componenthierarchy =
\
\
\
\
« niveau du module 11» = >
« module» = > […]
],
« niveau du module 12» = >
\
« niveau du module 121» = >
« module» = > […]
[1]
[1]
[1]
[1]
],
\
\
« niveau du module 21» = >
« module» = > […]
[1]
[1]
[1]
[1]
[1]
[1]
La relation entre les modules est strictement définie de haut en bas: un module encapsule d’autres modules, sait qui ils sont, mais ne sait pas et ne se soucie pas de savoir quels modules l’encapsulent.
Par exemple, dans la hiérarchie des composants ci – dessus, le module « module – niveau 1» sait comment emballer les modules « module – niveau 11» et « module – niveau 12», et il sait également comment emballer « module – niveau 121» pendant la transmission; Mais module – Level 11 ne se soucie pas de qui l’emballe, donc il ne sait pas module – Level 1. En utilisant une structure basée sur les composants, nous avons ajouté les informations réelles requises pour chaque module, qui sont divisées en paramètres (tels que les valeurs de configuration et d’autres attributs) et données (tels que les ID d’objet de base de données interrogés et d’autres attributs) et placées en conséquence sous les entrées de configuration de module et de configuration de module:
$Component Hierarchy Data =
\
\
\
Un objet commun (comme deux articles du même auteur). En d’autres termes, les données d’un objet de base de données sont normalisées. La structure est un dictionnaire organisé d’abord sous chaque type d’objet, puis sous l’id de l’objet, à partir duquel nous pouvons obtenir les propriétés de l’objet: $componenthierarchydata =
Je…
« base de données» = >
\
\
\
Je…
],
Je…
],
Je…
[1]
[1]
Par exemple, l’objet sous – jacent contient une hiérarchie de composants qui contient deux modules, page = > post – feed, où le module post – feed récupère les billets de blog. Veuillez noter ce qui suit:
Chaque module sait quel objet est interrogé par la propriété dbobjectid (les ID du billet de blog sont 4 et 9). Chaque module connaît le type d’objet de l’objet interrogé par la propriété dbkeys (les données de chaque billet sont sous \
« données du module» = >
« par» = >
\
« feed – back» = >
\
[1]
[1]
[1]
],
\
« par» = >
\
« feed – back» = >
\
‘id’ = > \
« auteur» = > « utilisateur»
[1]
[1]
[1]
[1]
],
« base de données» = >
‘post’ = >
4 = >
« title» = > « Hello, the world! »,
\
],
9 = >
« en – tête» = > « est – ce que tout va bien? »,
\
[1]
],
« utilisateur» = >
7 = >
« nom» = > « leo»
[1]
[1]
[1]
[1]
Chargement des données lorsque le formulaire affiche des propriétés dans un objet de base de données, le formulaire peut ne pas être au courant.
Et sera soumis à un nouveau champ: l’attribut \
Const post _ Widget Home = ‘post width
Auteur: Classe abstraite postwidgetlayoutabstractmoduleprocessor extension abstractmoduleprocessor
{Y}
Fonction getsubmodules ($modules): Tableau
{Y}
$ret =
$this – > getcontentmodule ($Module),
G);
Si ($Thumbnail _ module = $this – > getthumbnailmodule ($Module))
{Y}
$ret [] = $Thumbnail _ module;
}
Si ($aftercontent _ modules = $this – > getaftercontentmodules ($Module))
{Y}
$ret = array _ merge
$Oui,
$aftercontent _ module
);
}
Renvoie $RET;
}
Fonction de protection abstraite getcontentmodule ($Module): Tableau;
Fonction protégée getthumbnailmodule ($Module):? Beaucoup.
{Y}
Par défaut (réécrit)
Retourner [Self:: class, self:: Thumbnail _ Layout];
}
Fonctions protégées getaftercontentmodules ($modules): tableaux
{Y}
Renvoie [];
}
Fonction getimmutableconfiguration ($module, & $props): Tableau
{Y}
Retour
« Description» = > $this – > getdescription (),
G);
}
Fonction protégée getdescription ($Module): chaîne
{Y}
Renvoie »;
}
}
La classe moduleprocessor personnalise ensuite le moduleprocessor pour étendre la classe abstraite et définir ses propres propriétés: la classe postlayoutmoduleprocessor étend abstractpostlayoutmoduleprocessor {
Const post _ Context = ‘publish content’
Const post _ extract = ‘post – Extract’
Const post _ Thumbnail large = ‘Post thumbnail LARGE’
Const post _ Thumbnail medium = ‘Post thumbnail Medium’
Const post _ share = ‘post share’
Fonction getsubmodulestoprocess () {
Retour
Self:: Post _ content,
Self:: Post _ Extract,
Self:: Post _ Thumbnail page,
Self:: Post _ Thumbnail Medium,
Self:: Post _ Share,
G);
}
}
Classe postwidgetlayoutmoduleprocessor Extended Abstract postwidgetlayoutmoduleprocessor
{Y}
Fonction protégée getcontentmodule ($Module):? Beaucoup.
{Y}
Commutateur ($module [1])
{Y}
Case self:: Post _ Widget Homepage page:
Retour
Postlayoutmoduleprocessor:: class,
Postlayoutmodule Processor:: Post _ content
G);
Case self:: Post _ Widget Homepage Medium:
Case self:: Post _ Widget Homepage Small:
Retour
Postlayoutmoduleprocessor:: class,
Postlayoutmodule Processor:: Post _ Extract
G);
}
Renvoie le parent:: getcontentmodule ($Module);
}
Fonction protégée getthumbnailmodule ($Module):? Beaucoup.
{Y}
Commutateur ($module [1])
{Y}
Case self:: Post _ Widget Homepage page:
Retour
Postlayoutmoduleprocessor:: class,
Postlayoutmodule Processor:: Post _ Thumbnail Page
G);
Case self:: Post _ Widget Homepage Medium:
Retour
Postlayoutmoduleprocessor:: class,
Postlayoutmodule Processor:: Post _ Thumbnail Medium
G);
}
Renvoie le parent:: getthumbnailmodule ($Module);
}
Fonctions protégées getaftercontentmodules ($modules): tableaux
{Y}
$ret = [];
Commutateur ($module [1])
{Y}
Case self:: Post _ Widget Homepage page:
$Right [] =
Postlayoutmoduleprocessor:: class,
Postlayoutmodule Processor:: Post _ Share
G);
Casse – toi.
}
Renvoie $RET;
}
Fonction protégée getdescription ($Module): chaîne
{Y}
Retour \ \ (‘ce sont mes billets de blog,’ mon nom de domaine ‘);
}
}
Comment les composants s’adaptent naturellement au modèle de composants graphql vous permet naturellement de cartographier les requêtes graphql en forme d’arbre, ce qui en fait l’architecture idéale pour déployer un serveur graphql. Le graphql de POP implémente la classe moduleprocessor nécessaire pour convertir une requête graphql en une hiérarchie de composants appropriée et l’analyser à l’aide du moteur de chargement de données POP. C’est pourquoi et comment cette solution fonctionne. Mapping client components to graphql Queries les requêtes graphql peuvent être représentées en utilisant la hiérarchie des composants POP, où chaque type d’objet représente un composant et chaque champ de relation d’un type d’objet à un autre représente un composant qui peut être représenté par la hiérarchie des composants POP.
Et encapsule un autre composant. Prenons un exemple pour comprendre la situation. Supposons que nous construisions le Widget suivant \ Pays: {pays}
{foreach Films as films}
–>
Titre: {Titre}Image: {vignettes}
{foreach actors as actors}
♪ foreach ♪
–>
Nom: {name}Photo: {Avatar}
<!– Component:
Ensuite, nous déterminons quelles données sont nécessaires pour chaque composante. Pour
Nous avons besoin de noms et de portraits: <!– Component: Identifier les propriétés des données de chaque composant et construire une requête graphql pour récupérer les données demandées: requête {
Répertoire des fonctions
Nom
Pays
Avatar
Film
Titre
Vignettes
Acteur
Nom
Avatar
}
}
}
}
Comme vous pouvez le voir, il existe une relation directe entre la forme de la hiérarchie des composants et la requête graphql. En fait, les requêtes graphql peuvent également être considérées comme une hiérarchie représentant les composants. Résoudre une requête graphql en utilisant des composants côté serveur parce qu’une requête graphql a la même forme que la hiérarchie des composants, POP convertit la requête en sa hiérarchie équivalente des composants, l’analyse en utilisant sa méthode de récupération des données des composants, et enfin recréer la forme de la requête pour envoyer des données en réponse. Voyons comment ça marche. Pour traiter les données, POP convertit le type graphql en composant:
=> Participants et utilisation du document sur les exigences opérationnelles
Lorsqu’ils apparaissent dans la requête, POP crée une hiérarchie de composants virtuels avec les mêmes éléments: le composant racine du réalisateur, qui entoure le composant film, et le composant acteur. À partir de maintenant, il n’y a aucune différence à parler de type graphql ou de composant POP. Pour charger leurs données, POP les traite en itérations, récupérant chaque type de données objet dans ses itérations comme suit: <!– Component: Le moteur de chargement de données POP de type dans l’itération de gestion implémente le pseudo – algorithme suivant pour charger les données: Préparation: utiliser une file d’attente vide pour stocker la liste d’identification des objets à récupérer de la base de données, Organiser par type (chaque entrée sera: [type = > Liste d’identification]) pour récupérer l’id de l’objet de répertoire de premier plan et l’entrer dans la file d’attente sous la boucle du Contrôleur de type jusqu’à ce qu’il n’y ait plus d’entrées dans la file d’attente: obtenir la première entrée de la file d’attente: le type et la liste d’id (par exemple, le Contrôleur et [2]), Et supprimer cette entrée de la file d’attente pour lancer une seule requête de base de données pour récupérer tous les objets de ce type en utilisant ces ID, si le type a des champs relationnels (par exemple, le type de réalisateur a des films de champ relationnel de type film), Tous les id de ces champs sont ensuite recueillis à partir de tous les objets récupérés dans l’itération courante (par exemple, tous les ID dans les films de champ dans tous les objets de type réalisateur) et placés dans une file d’attente sous le type approprié (par exemple: ID [3, 8] sous le type de fichier). À la fin de l’itération, nous chargerons tous les types de données objet comme suit:
Cependant, si
Po a été traité, donc nous devons charger plus de données de ce type, et c’est la nouvelle itération sur ce type. Par exemple, lorsque vous ajoutez un champ de relation de directeur préféré au type d’auteur, le type de Contrôleur est ajouté à nouveau à la file d’attente: L’itération sur le type de répétition Notez également que nous pouvons utiliser le mécanisme de cache ici: dans la deuxième itération du type de contrôleur, l’objet avec ID 2 n’est plus récupéré parce qu’il a été récupéré dans la première itération, de sorte qu’il peut être récupéré à partir du cache. Maintenant que nous avons récupéré les données de tous les objets, nous devons les modéliser dans la réponse attendue pour refléter la requête graphql. Actuellement, les données sont organisées en une base de données relationnelle: tableaux par type contrôleur: Nom du pays ID Avatar film
3. | La menace des Wraith |
8. | Attaques de Clones | Episode 2. Jpg | [6, 7] |
4. | Ivan McGregor |
Portman | Portman. Jpg | |
Hayden Christensen | Christensen. Jpg |