Comment mettre en place les migrations avec Hasura
Le mercredi chez Mamelab, nous avons une journée de hackday qui nous permet de tester différentes technologies. Il y a peu de temps, j'ai choisi de m'intéresser au produit Hasura, un serveur GraphQL pour PostgreSQL.
J'ai pris l'exemple du tutoriel Angular Tour of heroes pour créer un CRUD en React avec l'aide d'Hasura pour le côté API et base de données. Vous pouvez retrouver le projet sur github.com/zyhou/heroes-hasura-react.
Si vous connaissez déjà Hasura, vous pouvez vous rendre directement à la partie Mise en place des migrations.
Hasura, c'est quoi ?
Régulièrement, nous découvrons de nouveaux outils et produits qui facilitent le développement d'API GraphQL. Hasura fait partie de ces outils.
Hasura est un serveur GraphQL qui utilise votre base de données Postgres pour générer une API GraphQL. On pourrait penser qu'il ressemble à un ORM traditionnel mais en fait il est bien plus puissant. Vous pouvez retrouver la liste de toutes les fonctionnalités sur leur site.
Pour en apprendre plus sur Hasura et comprendre pourquoi il est intéressant de l'utiliser, je vous laisse regarder la documentation officielle.
Mon avis sur Hasura
Hasura est vraiment très simple à mettre en place, il est en plus disponible sur beaucoup de services comme Heroku, Digital Ocean, Docker et AWS, etc...
En utilisant Hasura, j'ai découvert qu'il répondait à plusieurs besoins.
- Mettre en place rapidement un projet pour avoir une API fonctionnelle
- Pouvoir ajouter une partie Frontend React facilement grâce à
docker compose
- Faire le lien avec une base de données Postgres sans utiliser 50 frameworks différents
Le tutoriel d'introduction est rapide à réaliser. En quelques minutes, on se retrouve avec Hasura et une base de données Postgres. L'interface proposée pour l'administration est intuitive. Il est possible de créer facilement notre base de données, ainsi que mettre à jour le schéma GraphQL. Il propose GraphiQL et un éditeur SQL à la phpmyadmin.
On trouve rapidement les réponses aux questions que l'on peut se poser après la lecture du tutoriel d'introduction :
- Comment déployer notre projet ? lien vers la documentation
- Comment gérer l'authentification ? lien vers la documentation
- Comment être au courant des nouveautés ? https://blog.hasura.io/
- Est-ce que le projet est open-source ? github.com/hasura
D'après moi, la mise en place des migrations est la partie la plus obscure, nous y reviendrons en détail plus tard.
Ajouter sa propre logique métier
Avant cela, faisons un petit zoom sur l'ajout de logique métier. Hasura ne facilite pas la tâche dans ce domaine, il ne permet pas de spécifier un "resolver" particulier pour une requête d'API donnée. Hasura propose deux solutions.
La première solution est le schéma stitching. Sur le schéma de gauche où est présentée la notion de "remotes schemas", vous pouvez constater qu'Hasura a la capacité de fusionner des schémas GraphQL pour exposer un point unique d'API. La seconde solution, illustrée par le schéma de droite, est l'utilisation de webhooks.
Les webhooks sont sans doute plus faciles à mettre en place, car n'importe quelle API tierce peut prendre en charge la logique métier. Dans le cas du Schema Stitching, il faut forcément que la logique métier soit exposée elle aussi au travers d'une API GraphQL.
Les performances sont aussi une question non négligeable. Hasura génère automatiquement les requêtes SQL, elles ne sont pas aussi optimisées que si nous le faisions manuellement. Je me questionne sur ce qu'il pourrait en être avec une base de données conséquente ou encore avec des liens complexes entre les tables.
Et les migrations ?
Comme je l'ai souligné un peu plus haut, je trouve que la mise en place des migrations n'est pas la partie la plus claire. Avant de vous expliquer comment procéder, il faut revenir sur ce que signifie ce terme dans Hasura.
Nous avons deux choses bien distinctes :
- Les migrations de la base de données
- Les migrations GraphQL (les metadata)
Si vous avez déjà une base de données établie, vous devez avoir sûrement mis en place knex.js ou db-migrate, dans ce cas vous pouvez passer à la partie Migrations GraphQL.
Pourquoi avoir une migration au niveau de GraphQL me direz-vous ? Tout simplement parce que Hasura ne sait pas à quel moment vous modifiez la base de données. L'outil doit mettre à jour les schémas et les resolvers GraphQL. On peut soit utiliser le bouton "Untracked tables or views" qui se trouve dans la console Hasura, soit utiliser le cli (voir plus bas).
Il existe une série d'article sur le blog si vous voulez en savoir plus sur les schémas et les resolvers GraphQL.
Installation du CLI
Pour pouvoir utiliser les migrations, il faut installer le CLI d'Hasura. Pour ce faire, il existe deux façons.
Si vous avez suivi l'installation par docker, vous devez sûrement utiliser l'image hasura/graphql-engine:<version>
. Hasura propose une image docker qui contient le cli, on peut le trouver dans /bin/hasura-cli
.
hasura/graphql-engine:<version>.cli-migrations
Sinon vous pouvez installer simplement le cli sur votre machine, en suivant la documentation d'installation du cli.
Les migrations postgres
Il faut d'abord initialiser les migrations, ceci va créer un dossier migrations.
hasura init --directory migrations
Ensuite, vous pouvez constater qu'il existe plusieurs commandes pour appliquer, ajouter et supprimer des migrations.
hasura migrate apply
hasura migrate create migration-title
hasura migrate apply --down 1
La création de migrations va générer quatre fichiers, deux fichiers .sql
et deux .yaml
. Je vous conseille de supprimer les fichiers .yaml
. Ils me paraissent plus compliqués à utiliser que les fichiers .sql
.
On trouve un fichier *.up.sql
et *.down.sql
. Quand nous allons appliquer la migration, le fichier up.sql
va s'exécuter. Le fichier down.sql
quant à lui, sert à revenir en arrière si besoin..
Après chaque création ou suppression de migration, il ne faut pas oublier de faire la commande apply
.
Les migrations GraphQL
Deux commandes sont à connaître.
hasura metadata export
hasura metadata apply
L'export va créer un fichier metadata.yaml
, il inclut toutes les informations dont a besoin Hasura pour générer l'API GraphQL : nom des tables et schémas de la base de données, les remotes schema ainsi que les custom functions. Il faut lancer cette commande à chaque changement de base de données.
La commande apply
va simplement appliquer les données du fichier metadata.yaml
. Il n'est plus nécessaire de cliquer sur "Untracked tables or views".
TLDR
Copiez/collez cet extrait de code dans votre Makefile, et les migrations seront bien plus faciles.
##################
## Hasura cli Commands
##################
HASURA_CLI = docker-compose exec graphql-engine sh -ci "\
cd heroes-migrations/migrations && /bin/hasura-cli
migration-init: ## init directory migrations
docker-compose exec graphql-engine sh -ci "cd heroes-migrations && /bin/hasura-cli init --directory migrations"
migration-apply: ## apply migration
$(HASURA_CLI) migrate apply"
migration-new: ## make migration-new MIGRATION_TITLE=whatever-title
$(HASURA_CLI) migrate create ${MIGRATION_TITLE}"
migration-down: ## make migration-down NB_MIGRATIONS=whatever-number
$(HASURA_CLI) migrate apply --down ${NB_MIGRATIONS}"
metadata-export: ## export metadata graphql
$(HASURA_CLI) metadata export"
metadata-apply: ## apply metadata graphql
$(HASURA_CLI) metadata apply"
Je pars du principe que vous utilisez le cli Hasura dans docker, avec docker compose
Vous pouvez retrouver le projet d'exemple sur github.com/zyhou/heroes-hasura-react, un simple CRUD React avec Apollo-client et Hasura en serveur GraphQL avec une base de données postgres.
Conclusion
Hasura fut pour moi une découverte intéressante. Il simplifie grandement la mise en place de GraphQL et gère de manière autonome la base de données. Dans l'ensemble, la documentation est claire, comme nous avons pu le voir la mise en place des migrations est plus compliqué qu'il n'y parait.
L'utilisation du cli est intuitive, si vous avez déjà utilisé d'autre outils de migrations vous n'aurez aucun mal avec les commandes.
Si vous avez entendu parler d'Hasura avant cet article, vous avez sûrement dû entendre parler de Prisma, ils ont également rédigé un article sur Hasura vs Prisma.
Il y a de fortes chances que l'on parle de Prisma sur le blog, so stay tuned !