Quelqu'un a-t-il pensé à connecter Hasura à la base de données Postgres de Discourse pour un FE potentiellement plus personnalisé (ou ciblé) ?

[sondage type=multiple résultats=à_la_clôture min=1 max=6 typeGraph=pâte clôture=2020-04-30T10:00:00.000Z]

  • Essayé, bonne idée
  • Essayé, mauvaise idée
  • Pas encore essayé, mais ça semble intéressant
  • Pourquoi perdre votre temps avec ça ?
  • Je ne sais pas…
  • Autre
    [/sondage]

C’est super, c’est exactement ce que j’ai fait il y a quelques jours !
Je travaille avec Hasura/nuxt.js depuis un an sur différents projets.
Hasura est très puissant, et les fonctionnalités à venir sont très prometteuses !

J’aime beaucoup le forum Discourse (mais je ne connais pas Ruby et Ember), alors j’ai essayé de le connecter à Hasura.

Comme je ne suis pas développeur Ruby, j’ai dû l’installer, mais j’ai rencontré des problèmes pour configurer l’environnement de développement sur mon Mac. Je bute sur le gem cppjieba_rb

Alors j’ai simplement récupéré ce dump et je l’ai configuré dans PostgreSQL et Hasura.

Toutes les tables semblent avoir été importées. Il n’y a qu’une seule vue ? (badge_posts)
J’ai également tracé toutes les relations de clés étrangères, ce qui me permet d’effectuer ce type de requête :

{
  posts {
    id
    user_id
    bookmarks {
      id
      name
    }
    uploads {
      id
      url
    }
  }
}

Voilà où j’en suis pour le moment…

Wow, prometteur. Je vais essayer de démarrer un conteneur Hasura dans un environnement de production et de vous faire un retour sur les résultats. Nous pourrons comparer nos observations.

Pour votre information, pour obtenir un shell psql en cours d’exécution du serveur de base de données Postgres de Discourse en cours d’exécution, vous pouvez exécuter docker exec --user postgres -it app psql -d discourse. Ainsi, pour obtenir un dump complet, vous pouvez exécuter (notez que j’omette l’option -t ici car elle n’est pas nécessaire dans ce cas) :

docker exec --user postgres -i app pg_dump -Fc -d discourse > discourse.sql.pgcustom

Vous devriez maintenant pouvoir restaurer cela dans une instance Postgres conteneurisée (docker pull postgres:10.12) et la connecter à Hasura pour le développement (ce n’est vraiment utile qu’au niveau lecture seule car il s’agit désormais d’une base de données distincte).

Pour faire cela au niveau de la production, je configurerais l’environnement fourni par Discourse et j’hébergerais votre base de données dans un service comme Amazon RDS. Vous aurez alors un accès facile en lecture et écriture à cette base de données.

Pour restaurer le dump ci-dessus localement :

  1. Créez un réseau Docker :
docker network create discourse-dev-net
  1. Dans le premier terminal :
docker run --rm -it -p 2345:5432 -e POSTGRES_DB=discourse -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres --name=discourse-dev-pg --network=discourse-dev-net postgres:10.12

(Si vous souhaitez qu’il s’exécute en arrière-plan, je pense que vous pouvez simplement remplacer -it par -d ; -p 2345:5432 est optionnel mais pratique si vous souhaitez vous connecter à Postgres depuis votre hôte)

  1. Dans un autre terminal, créez l’utilisateur discourse dans Postgres (nécessaire pour le dump) :
docker run --rm -it -v /path/to/discourse.sql.pgcustom:/discourse.sql.pgcustom:ro -e PGPASSWORD=postgres --network=discourse-dev-net postgres:10.12 createuser -h discourse-dev-pg -U postgres -P discourse

(Vous saisissez ensuite le mot de passe deux fois à l’invite ; j’ai utilisé discourse comme mot de passe)

  1. Effectuez la restauration :
docker run --rm -i -v /home/dean/Downloads/discourse.sql.pgcustom:/discourse.sql.pgcustom:ro -e PGPASSWORD=postgres --network=discourse-dev-net postgres:10.12 pg_restore -h discourse-dev-pg -U postgres -d discourse /discourse.sql.pgcustom
  1. Pour connecter Hasura à ce dernier :
docker run --rm -it --network=discourse-dev-net -p 1234:1234 -e HASURA_GRAPHQL_ENABLE_CONSOLE=true -e HASURA_GRAPHQL_DATABASE_URL=postgres://postgres:postgres@discourse-dev-pg:5432/discourse hasura/graphql-engine:v1.2.1 graphql-engine serve --server-port=1234

(Vous pouvez maintenant accéder à http://localhost:1234)

Après avoir joué avec la base de données héritée, ce que @Falco dit dans ce post est très évident.

Peu de la puissance de Postgres est exploitée. Presque toute la logique est gérée côté Ruby.

Ma conclusion est donc que cela n’est pas très utile en soi.

Une autre approche consiste à utiliser la fonctionnalité de schéma distant de Hasura, mais pour cela, Discourse aurait besoin d’une API GraphQL, et non REST… donc là aussi, cela n’est pas très utile en soi.

Cependant, il est possible de encapsuler des API REST préexistantes dans une couche GraphQL. Cela semble plus prometteur que ce qui précède (ou plutôt, en combinaison avec ce qui précède). Dans cet article, ils pointent vers un dépôt avec du code de base pour démarrer.

Merci pour vos réponses.

Je ne maîtrise pas très bien Docker, mais mon problème ne vient pas de là. Comme je ne peux pas configurer un environnement de développement Discourse, je n’ai pas de base de données… Juste ce dump vide.

Quoi qu’il en soit, je viens de pousser ce dump sur une instance Heroku ! Vous pouvez donc l’essayer en direct :slight_smile:
Allez sur ce graphiql en ligne, et configurez ce point de terminaison :
https://discourse-hasura.herokuapp.com/v1/graphql
Vous pouvez jouer avec ! Il n’y a pas de mot de passe administrateur, vous pouvez donc aussi effectuer des mutations et des abonnements…

C’est ce que j’ai découvert en testant Discourse sur Hasura ! Toutes les fonctions personnalisées, les déclencheurs, les champs calculés… sont définis en Ruby. Mauvais pour la portabilité :confused:

Pas utile, il manque l’API GraphQL de Discourse. Mais c’est une fonctionnalité puissante de Hasura. Je l’utilise beaucoup avec une API GraphQL personnalisée de Stripe. Si nous avions une API GraphQL Discourse, nous pourrions la brancher sur notre propre GraphQL avec un schéma distant !

Oui, mais nous devons construire tout le schéma et les résolveurs. Beaucoup de travail !
Je pense qu’il est préférable d’utiliser l’API ouverte de Discourse ici : https://docs.discourse.org/ (dans le bouton de téléchargement), et de l’utiliser avec un générateur GraphQL comme https://graphql-mesh.com/docs/handlers/openapi
Je vais essayer dès que possible…

Ok, j’ai hâte ! J’ai essayé avec graphql-mesh.
Donc, le fichier OpenAPI sous le bouton de téléchargement sur https://docs.discourse.org/ semble cassé :confused:
J’ai testé la validité ici avec ce résultat :

Échec de la validation du schéma Swagger.
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/3
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/2
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/1
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/0
 
ÉCHEC_DE_LA_VALIDATION_OBJET_JSON

Erreur : Échec de la validation du schéma Swagger.
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/3
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/2
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/1
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/0
 
ÉCHEC_DE_LA_VALIDATION_OBJET_JSON
    à o (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:73766)
    à https://apitools.dev/swagger-parser/online/js/bundle.min.js:17:227596

ErreurSyntaxe : Échec de la validation du schéma Swagger.
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/3
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/3
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/2
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/2
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/1
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/1
  Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
    Les données ne correspondent à aucun schéma de 'oneOf' à #/paths//page_view_total_reqs/get/parameters/0
      Propriété requise manquante : schema à #/
      Propriété requise manquante : content à #/
    Propriété requise manquante : $ref à #/paths//page_view_total_reqs/get/parameters/0
 
ÉCHEC_DE_LA_VALIDATION_OBJET_JSON
    à Function.o [as syntax] (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:73766)
    à validateSchema (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:5021)
    à SwaggerParser.validate (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:3171)

Erreur de validation z-schema : ÉCHEC_DE_LA_VALIDATION_OBJET_JSON
    à ZSchema.getLastError (https://apitools.dev/swagger-parser/online/js/bundle.min.js:17:211187)
    à validateSchema (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:4925)
    à SwaggerParser.validate (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:3171)

Alors j’ai cherché un autre fichier OpenAPI ou Swagger de l’API Discourse. J’ai seulement trouvé celui-ci.
Il est un peu cassé à la ligne 426, mais je l’ai corrigé.

Après avoir configuré graphql-mesh, j’ai obtenu une API GraphQL fonctionnelle ! Mais…
Ce fichier Swagger n’est pas complet ou trop ancien. Il n’y a que 4 requêtes, pas de mutations, le type user avec très peu de propriétés… :confused:

Y a-t-il quelque part un fichier Swagger ou OpenAPI de Discourse ?

Un travail qui semble prometteur. Bravo ! Il serait bon que Discourse se conforme à certaines spécifications ouvertes comme Swagger/OpenAPI. J’espère que vous trouverez les informations que vous recherchez.

Je n’ai pas beaucoup de temps pour cela pour le moment, mais je reviendrai voir plus tard.

Travail intéressant. As-tu publié ce code quelque part pour voir quelles requêtes GraphQL sont possibles à l’état actuel ?

J’ai essayé de voter « Autre », mais cela n’a pas fonctionné.

Désolé pour cette réponse tardive. J’avais manqué votre question.
Oui, vous pouvez utiliser un endpoint GraphQL Hasura de Discourse :