有人想过将 Hasura 连接到 Discourse 的 Postgres 数据库,以实现更定制化(或更精简)的前端吗?

  • 试过了,是个好主意
  • 试过了,是个坏主意
  • 还没试过,但听起来很有趣
  • 为什么要浪费时间在这一点上?
  • 我不知道…
  • 其他
0 voters

太有趣了,这正是我几天前做的事!
我已经在不同项目中使用 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 正在运行的 PostgreSQL 数据库服务器的 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

之后即可将该转储文件恢复到容器化的 PostgreSQL 实例(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 为可选参数,但如果您希望从宿主机连接 PostgreSQL,则非常便利)

  1. 在另一个终端中,于 PostgreSQL 中创建 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

(随后会在提示符下要求输入两次密码,我使用的是 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 需要 GraphQL API,而不是 REST……因此这本身也没有太大帮助。

不过,我们可以将现有的 REST API 封装在 GraphQL 层中。这看起来比上述方案更有前景(或者更准确地说,与上述方案结合使用更有前景)。在这篇文章中,他们提到了一个包含入门样板代码的仓库

感谢您的回复。

我不是很精通 Docker,但问题并不在此。由于我无法设置 Discourse 开发环境,所以我没有数据库……只有这个空的转储文件。

无论如何,我刚刚将这个转储文件推送到 Heroku 实例中!所以您可以在线体验一下 :slight_smile:
前往 这个在线 GraphiQL,并设置以下端点:
https://discourse-hasura.herokuapp.com/v1/graphql
您可以随意尝试!这里没有管理员密码,因此您甚至可以进行变更操作和订阅…

这就是我在用 Hasura 测试 Discourse 时发现的!所有自定义函数、触发器、计算字段……都是在 Ruby 中定义的。这对可移植性不太有利 :confused:

确实帮助不大,因为缺少 Discourse 的 GraphQL API。但这是 Hasura 的一项强大功能。我经常用它来集成 Stripe 的自定义 GraphQL。如果我们能获得 Discourse 的 GraphQL API,就可以通过远程架构将其接入我们自己的 GraphQL 中!

是的,但我们必须构建整个架构和解析器,工作量很大!
我认为在这里使用 Discourse 的开放 API 更好:https://docs.discourse.org/(点击下载按钮),然后配合 GraphQL 生成器使用,例如 https://graphql-mesh.com/docs/handlers/openapi
我会尽快尝试……

好的,迫不及待了!我尝试使用了 graphql-mesh。

所以,https://docs.discourse.org/ 下载按钮下的 openapi 文件似乎已损坏 :confused:

我在此处测试了有效性:https://apitools.dev/swagger-parser/online/#,输出结果如下:

Swagger 架构验证失败。
  数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/3
  数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/2
  数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/1
  数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/0
 
JSON_OBJECT_VALIDATION_FAILED

错误:Swagger 架构验证失败。
  数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/3
  数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/2
  数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/1
  数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$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 架构验证失败。
  数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/3 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/3
  数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/2 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/2
  数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/1 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$ref at #/paths//page_view_total_reqs/get/parameters/1
  数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
    数据在 #/paths//page_view_total_reqs/get/parameters/0 处不匹配任何 'oneOf' 架构
      缺少必需属性:schema at #/
      缺少必需属性:content at #/
    缺少必需属性:$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 验证错误: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 个查询,没有变异操作,user 类型的属性也很少……:confused:

Discourse 的 swagger 或 openapi 文件在哪里可以找到呢?

听起来很有前景的工作。做得好!如果 Discourse 能遵循一些开放规范(如 Swagger/OpenAPI)就好了。希望你能找到所需的信息。

我现在没太多时间处理这个,但稍后会再回来查看。

很有趣的工作。你是否有将这段代码发布到某个地方,以便查看当前状态下可能使用的 GraphQL 查询?

我尝试投票给“其他”,但没有成功。

抱歉回复晚了,我漏掉了您的问题。
是的,您可以使用 Discourse Hasura GraphQL 端点进行交互: