Anyone thought of connecting Hasura to Discourse's Postgres database for a potentially more customised (or narrowed down) FE?

  • Tried it, good idea
  • Tried it, bad idea
  • Haven’t tried it, but sounds interesting
  • Why would you waste your time on this?
  • I donno…
  • Other

0 voters

So fun, this is exactly what I did some days ago!
I’m working with Hasura/nuxt.js since one year on different projects.
Hasura is very powerful, and the coming features are very promising!

I very like discourse forum (but don’t know Ruby and Ember), so I tried to plug Hasura on it.

As I’m not ruby dev, I need to install it but I got some problems to install dev environment on my mac. I struggle with cppjieba_rb gem…

So I just take this dump and setting up in postgresql and Hasura.

All tables seems to be imported. There is only one view? (badge_posts)
I also tracked all foreign-keys relationships, so I can do this kind of query:

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

That’s where I am now…

1 Like

Wow, promissing. I would try start a Hasura container in a live environment and report on what I get. We can compare notes.

For your information, to get a running psql shell of a running Discourse’s Postgres database server you can do docker exec --user postgres -it app psql -d discourse, so to get a full dump you can do (note, I am dropping -t option here as it is not needed in this case):

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

Should now be able to restore that to a dockerized postgres (docker pull postgres:10.12) and connect it to Hasura for development (only really useful at read-only level because it is a seperate database now).

To do this on production level, I would set the environment discourse provides and host your database in something like Amazon RDS. You then have easy access to read and write to that database.

To restore the dump above locally:

  1. Create a docker network:
docker network create discourse-dev-net
  1. In first shell:
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

(If you want it running in background, I think you can just replace -it for -d; -p 2345:5432 is optional but convenient if you want to connect to postgres from your host)

  1. In another shell, create discourse user in postgres (needed for 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

(you then type password in prompt twice, I used discourse as password)

  1. Perform the restore:
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. To connect Hasura to the above:
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

(You can now visit http://localhost:1234)

Having had a play with the inherited database, what @Falco says in this post is very evident.

Not very much of Postgres’s power is used. Almost all of the logic is done in Ruby land.

So my conclusion is that this is not entirely helpful in itself at all.

Another approach is using Hasura’s remote schema functionality but to do that Discourse would need a GraphQL API, not REST… so also in itself not very helpful.

But there is the possibility to wrap pre-existing REST APIs within a GraphQL layer. This looks more promising than the above (or rather, in combination with the above). In this article, they point to a repository with boilerplate code to get started

2 Likes

Thanks for yours replies.

I don’t master docker very well, but my problem is not here. As I can’t set a discourse dev environment, I don’t have database… Just this empty dump.

Anyway, I just pushed this dump in a heroku instance! So you can try it live :slight_smile:
Go to this online graphiql, and set this endpoint:
https://discourse-hasura.herokuapp.com/v1/graphql
You can play with it! There’s no admin password, so you can also do mutations and subscriptions…

This is what I discovered when tested discourse on Hasura! All customs functions, triggers, computed fields… are defined in Ruby. Bad for portability :confused:

Not helpful, missing the discourse graphql api. But this is a powerful feature of Hasura. I use it a lot with a custom graphql of Stripe. If we got a discourse graphql API, we can plug it in our own graphql with remote schema!

Yes, but we have to build all the schema and resolvers. A lot of work!
I think it’s better to use the open api of discourse here: https://docs.discourse.org/ (in the download button), and use it with a graphql generator like OpenAPI / Swagger
I will try as soon as possible…

Ok can’t wait!. I tried with graphql-mesh.
So, the openapi file under the download button in https://docs.discourse.org/ seems broken :confused:
I tested validity here with this output:

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)

So I searched for another openapi or swagger file of the discourse api. I just found this one.
It’s little broken line 426, but I fixed it.

After set graphql-mesh, I got a working graphql api! But…
This swagger file is not complete or too old. There is only 4 queries, no mutations, type user as few properties… :confused:

Is there somewhere a swagger or openapi file of discourse?

2 Likes

Promising sounding work. Well done! It would be good if Discourse conformed to some Open specs like Swagger/OpenAPI. Hope you find the information you are looking for.

I don’t have much time for this right now, but will check back sometime.

Interesting work. Do you have this code published anywhere to see what graphql queries are possible at the current state ?

I tried to vote Other but it did not work.

Sorry for the late response. I missed your question.
Yes, you can play with a discourse hasura graphql endpoint:

1 Like