HasuraをDiscourseのPostgresデータベースに接続して、よりカスタマイズされた(または絞り込まれた)フロントエンドを実現するアイデアはありますか?

  • 試しました、良いアイデア
  • 試しました、悪いアイデア
  • 試していませんが、面白そうです
  • なぜこんなことに時間を費やすのですか?
  • わからない…
  • その他
0 voters

とても楽しいですね!これはまさに数日前に私がやったことと全く同じです!
私は1年前からさまざまなプロジェクトで Hasura/nuxt.js を使っています。
Hasura は非常に強力であり、今後の機能も非常に有望です!

私は Discourse フォーラムが非常に気に入っていますが(Ruby と Ember は知りません)、Hasura をそれと連携させることを試みました。

Ruby 開発者ではないため、インストールが必要でしたが、Mac 上の開発環境のインストールでいくつかの問題に直面しました。cppjieba_rb gem に苦労しています…

そのため、このダンプ を取得し、PostgreSQL と Hasura でセットアップしました。

すべてのテーブルがインポートされたようです。ビューは一つだけですか?(badge_posts)
また、すべての外部キー関係を追跡したため、このようなクエリを実行できます:

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

これが現在の状況です…

おぉ、有望ですね。本番環境で Hasura コンテナを起動して、その結果を報告してみましょう。情報を共有し合いましょう。

参考までに、実行中の Discourse の Postgres データベースサーバーの psql シェルを取得するには、docker exec --user postgres -it app psql -d discourseを実行します。完全なダンプを取得するには、以下のコマンドを実行してください(この場合、-t オプションは不要なため省略しています):

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

これで、docker 化された Postgres(docker pull postgres:10.12)に復元し、開発用に Hasura に接続できるようになります(ただし、現在は別のデータベースになっているため、読み取り専用レベルでのみ実際に役立ちます)。

本番環境でこれを行うには、Discourse が提供する環境変数を設定し、データベースを Amazon RDS などのサービスでホストすることをお勧めします。これにより、データベースへの読み書きが容易になります。

上記のダンプをローカルで復元するには:

  1. Docker ネットワークを作成します:
docker network create discourse-dev-net
  1. 最初のシェルで:
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

(バックグラウンドで実行したい場合は、-it-d に置き換えるだけでよいと思います。-p 2345:5432 はオプションですが、ホストから Postgres に接続する際に便利です)

  1. 別のシェルで、Postgres に discourse ユーザーを作成します(ダンプに必要です):
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

(プロンプトでパスワードを 2 回入力します。私はパスワードに discourse を使用しました)

  1. 復元を実行します:
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. 上記のデータベースに Hasura を接続するには:
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

(これで http://localhost:1234 にアクセスできるようになります)

継承されたデータベースを触ってみて、@Falcoこの投稿で述べていることは非常に明白です。

Postgres の機能はほとんど活用されていません。ロジックのほとんどは Ruby 側で処理されています。

したがって、私の結論としては、これだけでは全く役立たないということです。

別のアプローチとして、Hasura のリモートスキーマ機能を利用する方法がありますが、そのためには Discourse に REST ではなく GraphQL API が必要となるため、これも単独ではあまり役立ちません。

ただし、既存の REST API を GraphQL レイヤーでラップするという選択肢もあります。これは上記のアプローチよりも有望に見えます(あるいは、上記と組み合わせることでより有効です)。この記事では、着手するためのボイラープレートコードを含むリポジトリが紹介されています。

返信ありがとうございます。

Docker の操作にはあまり慣れていませんが、私の問題はそこではありません。Discourse の開発環境を設定できないため、データベースも持っておらず、この空のダンプファイルしかありません。

とにかく、このダンプを Heroku インスタンスにプッシュしました!ライブで試してみてください :slight_smile:
このオンライン GraphiQL にアクセスし、以下のエンドポイントを設定してください:
https://discourse-hasura.herokuapp.com/v1/graphql
自由に遊んでみてください!管理者パスワードは不要なので、ミューテーションやサブスクリプションも実行できます。

これは、Discourse を Hasura でテストした際に発見したことです。すべてのカスタム関数、トリガー、計算フィールドなどは Ruby で定義されています。移植性の面で問題があります :confused:

確かに役立ちません。Discourse の GraphQL API が欠落しているためです。しかし、これは Hasura の強力な機能です。私は Stripe のカスタム GraphQL と一緒にこの機能をよく使っています。Discourse に GraphQL API があれば、リモートスキーマを使って独自の GraphQL に接続できます!

はい、しかしすべてのスキーマとリゾルバを構築する必要があります。かなり大変な作業です!
私はここで Discourse のオープン API を使う方が良いと思います:https://docs.discourse.org/(ダウンロードボタン内)。そして、https://graphql-mesh.com/docs/handlers/openapi のような GraphQL ジェネレーターと組み合わせて使用します。
できるだけ早く試してみます…

はい、待ちきれません!graphql-mesh で試してみました。
https://docs.discourse.org/ のダウンロードボタンにある openapi ファイルは壊れているようです :confused:
この出力で 有効性をテスト しました:

Swagger スキーマ検証に失敗しました。
  #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/3 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/2 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/1 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/0 に必要なプロパティ '$ref' が不足しています
 
JSON_OBJECT_VALIDATION_FAILED

エラー: Swagger スキーマ検証に失敗しました。
  #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/3 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/2 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/1 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/0 に必要なプロパティ '$ref' が不足しています
 
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 スキーマ検証に失敗しました。
  #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/3 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/3 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/2 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/2 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/1 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/1 に必要なプロパティ '$ref' が不足しています
  #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
    #/paths//page_view_total_reqs/get/parameters/0 の 'oneOf' のいずれかのスキーマとデータが一致しません
      #/ に必要なプロパティ 'schema' が不足しています
      #/ に必要なプロパティ 'content' が不足しています
    #/paths//page_view_total_reqs/get/parameters/0 に必要なプロパティ '$ref' が不足しています
 
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 検証エラー: 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)

そこで、Discourse API の別の openapi または swagger ファイルを探しました。これ しか見つかりませんでした。
426 行目が少し壊れていましたが、修正しました。

graphql-mesh を設定した後、動作する graphql API が手に入りました!でも…
この swagger ファイルは不完全か、古すぎます。クエリは 4 つだけで、ミューテーションはなく、type user のプロパティも非常に少ないです… :confused:

Discourse の swagger または openapi ファイルはどこかにありますか?

有望そうな取り組みですね。お疲れ様でした!Discourse が Swagger/OpenAPI などのオープン仕様に対応すると良いですね。お探しの情報が見つかることを願っています。

今は時間があまり取れませんが、後でまた確認します。

興味深い作業ですね。現在の状態で可能な GraphQL クエリを確認するために、このコードをどこかに公開されていますか?

「その他」に投票しようとしましたが、うまくいきませんでした。

返信が遅くなり申し訳ありません。質問を見落としていました。
はい、Discourse Hasura GraphQL エンドポイントを使って遊ぶことができます: