Кто-нибудь думал о подключении Hasura к базе данных PostgreSQL Discourse для более кастомизированного (или узкоспециализированного) фронтенда?

  • Пробовал(а), хорошая идея
  • Пробовал(а), плохая идея
  • Не пробовал(а), но звучит интересно
  • Зачем тратить на это время?
  • Не знаю…
  • Другое
0 voters

Как здорово, я сделал именно это несколько дней назад!
Я работаю с Hasura и nuxt.js уже год над разными проектами.
Hasura очень мощная, и предстоящие функции выглядят очень перспективно!

Мне очень нравится форум Discourse (но я не знаю Ruby и Ember), поэтому я попробовал подключить к нему Hasura.

Так как я не разработчик на Ruby, мне нужно было установить его, но у меня возникли проблемы с настройкой среды разработки на Mac. Я застрял на геме cppjieba_rb

Поэтому я просто взял этот дамп, настроил его в PostgreSQL и Hasura.

Кажется, все таблицы импортированы. Есть только один вид? (badge_posts)
Я также проследил все связи внешних ключей, поэтому могу выполнять такие запросы:

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

Вот на чём я сейчас остановился…

Вау, многообещающе. Я бы попробовал запустить контейнер Hasura в рабочей среде и отчитался о результатах. Можем сравнить заметки.

К вашему сведению, чтобы получить работающую оболочку psql для работающего сервера баз данных Postgres в Discourse, можно выполнить команду docker exec --user postgres -it app psql -d discourse. Чтобы получить полный дамп, выполните следующее (обратите внимание, что я опускаю опцию -t, так как в данном случае она не нужна):

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

Теперь вы сможете восстановить этот дамп в докеризованный 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. В другом терминале создайте пользователя discourse в Postgres (необходимо для дампа):
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
Вы можете поэкспериментировать с ним! Здесь нет пароля администратора, поэтому вы также можете выполнять мутации и подписки…

Именно это я обнаружил, тестируя Discourse с Hasura! Все пользовательские функции, триггеры, вычисляемые поля… определены на Ruby. Это плохо для переносимости :confused:

Не помогает, так как отсутствует GraphQL API Discourse. Но это мощная функция Hasura. Я часто использую её вместе с пользовательским GraphQL API Stripe. Если у нас появится GraphQL API Discourse, мы сможем подключить его к нашему собственному GraphQL с помощью удалённых схем!

Да, но нам придётся создать всю схему и резольверы. Это много работы!
Я думаю, что лучше использовать открытый API Discourse здесь: https://docs.discourse.org/ (в кнопке загрузки) и применять его с генератором GraphQL, например https://graphql-mesh.com/docs/handlers/openapi
Я попробую как можно скорее…

Окей, не могу дождаться! Я пробовал с graphql-mesh.
Итак, файл OpenAPI под кнопкой загрузки на https://docs.discourse.org/ кажется битым :confused:
Я проверил валидность здесь с этим выводом:

Сбой валидации схемы Swagger.
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/3
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/2
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/1
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/0
 
JSON_OBJECT_VALIDATION_FAILED

Ошибка: Сбой валидации схемы Swagger.
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/3
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/2
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/1
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/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.
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/3
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/3
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/2
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/2
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/1
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/paths//page_view_total_reqs/get/parameters/1
  Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
    Данные не соответствуют ни одной схеме из 'oneOf' в #/paths//page_view_total_reqs/get/parameters/0
      Отсутствует обязательное свойство: schema в #/
      Отсутствует обязательное свойство: content в #/
    Отсутствует обязательное свойство: $ref в #/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)

Поэтому я поискал другой файл OpenAPI или Swagger для API Discourse. Нашел только этот.
Он немного битый на строке 426, но я исправил это.

После настройки graphql-mesh я получил работающий GraphQL API! Но…
Этот файл Swagger неполный или устаревший. Есть только 4 запроса, нет мутаций, тип user с малым количеством свойств… :confused:

Есть ли где-то файл Swagger или OpenAPI для Discourse?

Звучит как многообещающая работа. Молодцы! Было бы хорошо, если бы Discourse соответствовал некоторым открытым спецификациям, таким как Swagger/OpenAPI. Надеюсь, вы найдёте нужную информацию.

Сейчас у меня нет на это много времени, но я вернусь к этому позже.

Интересная работа. Опубликовали ли вы этот код где-нибудь, чтобы можно было посмотреть, какие GraphQL-запросы возможны на текущем этапе?

Я попытался проголосовать за «Другое», но это не сработало.

Извините за поздний ответ. Я пропустил ваш вопрос.
Да, вы можете работать с конечной точкой GraphQL для Discourse Hasura: