¿Alguien ha pensado en conectar Hasura a la base de datos Postgres de Discourse para un FE potencialmente más personalizado (o reducido)?

  • Lo probé, buena idea
  • Lo probé, mala idea
  • No lo he probado, pero suena interesante
  • ¿Por qué perderías el tiempo con esto?
  • No lo sé…
  • Otro
0 voters

¡Qué divertido, esto es exactamente lo que hice hace unos días!

Trabajo con Hasura/nuxt.js desde hace un año en diferentes proyectos. Hasura es muy potente y las próximas funciones son muy prometedoras.

Me gusta mucho el foro de Discourse (aunque no sé Ruby ni Ember), así que intenté conectar Hasura con él.

Como no soy desarrollador de Ruby, necesito instalarlo, pero tuve algunos problemas al configurar el entorno de desarrollo en mi Mac. Me estoy topando con el gem cppjieba_rb

Así que simplemente tomé este volcado y lo configuré en PostgreSQL y Hasura.

Parece que todas las tablas se importaron correctamente. ¿Solo hay una vista? (badge_posts)
También rastree todas las relaciones de claves foráneas, así que puedo hacer este tipo de consulta:

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

Ese es mi punto de partida por ahora…

¡Vaya, prometedor! Intentaría iniciar un contenedor de Hasura en un entorno en vivo y reportar lo que obtenga. Podemos comparar notas.

Para su información, para obtener una shell de psql en ejecución del servidor de base de datos Postgres de Discourse en ejecución, puede ejecutar docker exec --user postgres -it app psql -d discourse. Así, para obtener un volcado completo, puede ejecutar (tenga en cuenta que estoy omitiendo la opción -t aquí, ya que no es necesaria en este caso):

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

Ahora debería poder restaurarlo en una base de datos Postgres en Docker (docker pull postgres:10.12) y conectarla a Hasura para desarrollo (realmente útil solo a nivel de solo lectura, ya que ahora es una base de datos separada).

Para hacer esto a nivel de producción, configuraría el entorno que proporciona Discourse y alojaría su base de datos en algo como Amazon RDS. De esta manera, tendrá acceso fácil para leer y escribir en esa base de datos.

Para restaurar el volcado anterior localmente:

  1. Cree una red de Docker:
docker network create discourse-dev-net
  1. En la primera 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 desea que se ejecute en segundo plano, creo que puede simplemente reemplazar -it por -d; -p 2345:5432 es opcional pero conveniente si desea conectarse a Postgres desde su host)

  1. En otra terminal, cree el usuario de Discourse en Postgres (necesario para el volcado):
docker run --rm -it -v /ruta/al/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

(luego ingrese la contraseña dos veces cuando se le solicite; yo usé discourse como contraseña)

  1. Realice la restauración:
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. Para conectar Hasura con lo anterior:
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

(Ahora puede visitar http://localhost:1234)

Después de probar la base de datos heredada, es muy evidente lo que @Falco dice en este post.

No se aprovecha mucho del poder de Postgres. Casi toda la lógica se implementa en Ruby.

Por lo tanto, mi conclusión es que esto no es en sí mismo particularmente útil.

Otra opción es utilizar la funcionalidad de esquema remoto de Hasura, pero para ello Discourse necesitaría una API GraphQL, no REST… por lo que tampoco es muy útil por sí sola.

Sin embargo, existe la posibilidad de envolver APIs REST preexistentes en una capa GraphQL. Esto parece más prometedor que lo anterior (o mejor dicho, en combinación con lo anterior). En este artículo, señalan un repositorio con código de plantilla para empezar.

Gracias por vuestras respuestas.

No domino Docker muy bien, pero mi problema no está ahí. Como no puedo configurar un entorno de desarrollo de Discourse, no tengo base de datos… Solo este volcado vacío.

De todos modos, ¡acabo de subir este volcado a una instancia de Heroku! Así que podéis probarlo en vivo :slight_smile:
Id a este GraphiQL en línea y configurad este endpoint:
https://discourse-hasura.herokuapp.com/v1/graphql
¡Podeis jugar con él! No hay contraseña de administrador, así que también podéis realizar mutaciones y suscripciones…

Esto es lo que descubrí al probar Discourse con Hasura: todas las funciones personalizadas, triggers, campos calculados… están definidos en Ruby. Malo para la portabilidad :confused:

No es útil, falta la API GraphQL de Discourse. Pero esta es una característica poderosa de Hasura. La uso mucho con una GraphQL personalizada de Stripe. Si tuviéramos una API GraphQL de Discourse, ¡podríamos integrarla en nuestra propia GraphQL con esquema remoto!

Sí, pero tendríamos que construir todo el esquema y los resolvers. ¡Mucho trabajo!
Creo que es mejor usar la API abierta de Discourse aquí: https://docs.discourse.org/ (en el botón de descarga), y utilizarla con un generador GraphQL como https://graphql-mesh.com/docs/handlers/openapi
Lo probaré tan pronto como pueda…

¡Ok, no puedo esperar! Probé con graphql-mesh.
Entonces, el archivo OpenAPI bajo el botón de descarga en https://docs.discourse.org/ parece estar roto :confused:
Probé la validez aquí con este resultado:

Swagger schema validation failed. 
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/3
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/2
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/1
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/0
 
JSON_OBJECT_VALIDATION_FAILED

Error: Swagger schema validation failed. 
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/3
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/2
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/1
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/0
 
JSON_OBJECT_VALIDATION_FAILED
    at o (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:73766)
    at https://apitools.dev/swagger-parser/online/js/bundle.min.js:17:227596

SyntaxError: Swagger schema validation failed. 
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/3
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/3
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/2
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/2
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/1
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/1
  Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
    Data does not match any schemas from 'oneOf' at #/paths//page_view_total_reqs/get/parameters/0
      Missing required property: schema at #/
      Missing required property: content at #/
    Missing required property: $ref at #/paths//page_view_total_reqs/get/parameters/0
 
JSON_OBJECT_VALIDATION_FAILED
    at Function.o [as syntax] (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:73766)
    at validateSchema (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:5021)
    at SwaggerParser.validate (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:3171)

z-schema validation error: JSON_OBJECT_VALIDATION_FAILED
    at ZSchema.getLastError (https://apitools.dev/swagger-parser/online/js/bundle.min.js:17:211187)
    at validateSchema (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:4925)
    at SwaggerParser.validate (https://apitools.dev/swagger-parser/online/js/bundle.min.js:1:3171)

Así que busqué otro archivo OpenAPI o Swagger de la API de Discourse. Solo encontré este.
Está un poco roto en la línea 426, pero lo arreglé.

Después de configurar graphql-mesh, ¡obtuve una API GraphQL funcional! Pero…
Este archivo Swagger no está completo o es demasiado antiguo. Solo hay 4 consultas, ninguna mutación, el tipo user con pocas propiedades… :confused:

¿Existe en algún lugar un archivo Swagger u OpenAPI de Discourse?

Trabajo con un sonido prometedor. ¡Bien hecho! Sería bueno que Discourse se ajustara a algunas especificaciones abiertas como Swagger/OpenAPI. Espero que encuentres la información que buscas.

En este momento no tengo mucho tiempo para esto, pero volveré a revisar en algún momento.

Trabajo interesante. ¿Tienes este código publicado en algún lugar para ver qué consultas graphql son posibles en el estado actual?

Intenté votar “Otro”, pero no funcionó.

Lo siento por la respuesta tardía. Me perdí tu pregunta.
Sí, puedes probar con un endpoint de GraphQL de Discourse Hasura: