Slide 1

Slide 1 text

La nouvelle API GraphQL chez Allociné CODE RHAPSODIE www.code-rhapsodie.fr / [email protected]

Slide 2

Slide 2 text

L’API GraphQL d’Allociné Jimmy Escrich – Allociné (Webedia) @escrichjimmy | @Ciloe Arnaud Lafon – Code Rhapsodie @arnaudlafon | @alafon Ceci n’est pas un talk sur GraphQL

Slide 3

Slide 3 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL Et les clients dans tout ça What else ?

Slide 4

Slide 4 text

● ● ● ● ● ● ● Il était une fois en 2016… Une API viellissante en .NET et MSSQL Une refonte sous Symfony de www Une refonte en cours de la db avec PG Des copains qui jouent avec Graph Un truc qui s’appelle Facebook Une refonte de l’appli mobile à venir 20 devs ~ |agile | 3-4 chantiers en //

Slide 5

Slide 5 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 6

Slide 6 text

● ● ● ● GraphQL en quelques mots HHVM vers NodeJS Spécifications : typage fort, etc Taillé pour de l’asynchrone Résolution des fields à la demande et de manière indépendante les uns des autres http://facebook.github.io/graphql/October2016/

Slide 7

Slide 7 text

GraphQL en quelques mots GraphiQL, l'outil du développeur !

Slide 8

Slide 8 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 9

Slide 9 text

● ● ● La R&D chez Overblog : Le commencement Création de la librairie GraphQLPhpGenerator Génère du code Webonyx (cache) Surcouche de configuration forte en php Pas de magie !

Slide 10

Slide 10 text

● ● ● La R&D chez Overblog : Le commencement Modif implem NodeJS => diff => Webonyx Gros avantage de notre coté : Þ Pas de modification de la config PHP Þ Juste à faire évoluer le générateur Ajout de nouveaux composants (graphql- bundle) => surcouche en yaml

Slide 11

Slide 11 text

La R&D chez Overblog : Le commencement Déclaration avec Webonyx Déclaration avec le bundle Overblog

Slide 12

Slide 12 text

● ● ● ● La R&D chez Overblog : L'évolution ACL : visibilité & accès Obfuscation erreurs Webonyx en prod Compatibilité avec les promesses Portage du JS jusqu'à sa version stable

Slide 13

Slide 13 text

● ● ● La R&D chez Overblog : Et après ? Un des contributeurs majeurs de webonyx/graphql-php Découplage de GraphiQL dans un bundle séparé, utilisé par Webonyx Sortir de la dépendance à Symfony

Slide 14

Slide 14 text

● ● La R&D chez Overblog : Et après ? Analyser de complexité Proposer un graph client PHP Génération des queries en cache Asynchronisation par promesses Un « query builder » de vos requêtes #

Slide 15

Slide 15 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 16

Slide 16 text

● ● Le projet de refonte de l’API - 1 On your marks, get set, … pas go Webonyx vs Youshido • Portage vs « from scratch » • ~ 2 mois de benchmark • 2 micro-kernels Symfony • Plusieurs « backends » pour l’exécution • On n’utilise pas le bundle d’Overblog • On mesure ! (grafana, telegraf, influxdb, …)

Slide 17

Slide 17 text

● ● ● ● ● Le projet de refonte de l’API - 2 Perfs : ~ Framework : Youshido plutôt sexy Communauté : Webonyx ++ Facilité d’implémentation : ~ Relay pas « natif »

Slide 18

Slide 18 text

Le projet de refonte de l’API - 3 • Bundle d’Overblog à faire évoluer pour la pagination • Système de promesses à creuser pour résoudre les problématiques de charge (on laisse de coté les forks pcntl & co pour le moment) • Cache Redis à améliorer

Slide 19

Slide 19 text

● Le projet de refonte de l’API - 4 Au final GraphQL se prête bien à : - nos entités ciné & co - un projet en perpétuelle évolution - des changements de backend - des refactos régulières - des stories qui arrivent au compte goutte

Slide 20

Slide 20 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 21

Slide 21 text

● ● ● ● ● ● ● La stack de dev Docker / Compose (Apache|Nginx) + php-fpm Pas besoin de Doctrine (yayy) PDO pour le moment Redis, Elasticsearch Symfony 3.4.*|4.* CI : Phpunit, Jenkins, Github, GCP (registry docker)

Slide 22

Slide 22 text

● La stack de dev - profiler Sf Profiler

Slide 23

Slide 23 text

La stack de dev - profiler

Slide 24

Slide 24 text

La stack de dev - profiler Film: ‘Deadpool 2’ Un cinéma donné Le titre du film Les 2 premiers acteurs avec leur role Une liste de séances

Slide 25

Slide 25 text

La stack de dev - profiler 2 requêtes au backend Elasticsearch Pas de cache Retourne des ids

Slide 26

Slide 26 text

La stack de dev - profiler 4 requêtes à dataloader Cache Redis sur chacune des requêtes

Slide 27

Slide 27 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 28

Slide 28 text

● Des promesses et du cache – 1 Problématique 1 : cache d’une entité Ex : 1 Film => SELECT FROM movie.movie WHERE Cache = Redis Facile !

Slide 29

Slide 29 text

● Des promesses et du cache – 2 Problématique 2 : les listes simples Ex : une liste de 10 films => SELECT * FROM movie.movie LIMIT 10; Et si nouvelle query avec OFFSET = 5 ?? => Cache again ??? => Cache ???

Slide 30

Slide 30 text

● Des promesses et du cache – 3 Problématique 3 : les (vraies) listes Ex : une liste de films avec des filtres et qui ont probablement des acteurs en communs SELECT * FROM movie.movie + JOIN sur casting + JOIN sur person + etc => Cache ???

Slide 31

Slide 31 text

● ● ● ● Solution : dataloader & promesses Implémentation en PHP chez Overblog 1 dataloader par entité, voire par besoin Dataloader fallback sur un backend de données et gère le cache Des promesses et du cache – 4

Slide 32

Slide 32 text

● ● ● ● ● ● Le(s) backend(s) retourne(nt) ids Dataloader fait des promesses On dépile : - check le cache pour chaque id - une requête pour les ids manquants - mise en cache pour chaque id Des promesses et du cache – 5

Slide 33

Slide 33 text

Des promesses et du cache – 6 L’implémentation dataloader de base

Slide 34

Slide 34 text

Des promesses et du cache – 7 Load d’une clé donnée Une promesse peut-être déjà présente en cache Sinon on la créé On l’ajoute à une queue On peut choisir de batcher les promesses ou les exécuter directement

Slide 35

Slide 35 text

Des promesses et du cache – 8 Plusieurs clés => ? Plusieurs appels à load($key) Création de plusieurs promesses qui appellent load($key) dans un callback

Slide 36

Slide 36 text

Des promesses et du cache – 9 Réimplémentation de la méthode load() Si pas de hit : on encapsule le load() de base dans un mécanisme de cache. Sinon, on retourne une promesse considérée comme « remplie ».

Slide 37

Slide 37 text

Des promesses et du cache – 10 Dataloader générique pour toutes nos entités Graph Définition du callable qui permet d’avoir des clés de cache uniques même lorsque des clés sont un tableau de paramètres. Définition du callable responsable du chargement d’une liste d’ids via un callable.

Slide 38

Slide 38 text

Des promesses et du cache – 11

Slide 39

Slide 39 text

Des promesses et du cache – 12 callable

Slide 40

Slide 40 text

Des promesses et du cache – 13

Slide 41

Slide 41 text

Des promesses et du cache – 14 Parser GraphQL (Webonyx + bridge OB) Resolver Elasticsearch (retourne ids ) Construction des promesses (Dataloader) Cache de promesse (Redis) Exécution des promesses renvoyées par les dataloaders Promesse m call_user_func(callable, $ids) Cache d’entité (Redis) Promesse n ( fulfilled ) callable $repo ->find($ids) JSON

Slide 42

Slide 42 text

Des promesses et du cache – 15 Multi-queries & alias 2 requêtes Elasticsearch Mais : - une seule stack de promesse - Dataloader + cache redis qui font le job ! !

Slide 43

Slide 43 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 44

Slide 44 text

● ● ● ● Sécurité Stateless Authentication : JWT Expiration => base de données Cache

Slide 45

Slide 45 text

Sécurité

Slide 46

Slide 46 text

ACL une application => plusieurs schemas surcharge de la visibilité et de l’accès aux champs

Slide 47

Slide 47 text

ACL

Slide 48

Slide 48 text

L’API GraphQL d’Allociné L’histoire du projet GraphQL en quelques mots Les librairies PHP, bundles et R&D Le projet de refonte de l’API Notre stack de dev Des promesses et du cache Un peu de sécurité et d'ACL What else ?

Slide 49

Slide 49 text

● ● ● ● ● What else ? Mutations (écritures) pomm-project/pomm-bundle * Broker de message pour certaines opérations (php-fpm obligatoire) Migration vers Sf4 API publique ? J http://www.pomm-project.org/

Slide 50

Slide 50 text

● ● ● ● ● What else ? github.com/overblog/GraphQLBundle github.com/overblog/GraphiQLBundle github.com/overblog/dataloader-bundle github.com/overblog/GraphQLPhpGenerator github.com/overblog/dataloader-php

Slide 51

Slide 51 text

L’API GraphQL d’Allociné Jimmy Escrich – Allociné (Webedia) @escrichjimmy | @Ciloe Arnaud Lafon – Code Rhapsodie @arnaudlafon | @alafon https://joind.in/talk/3e2cf