# Hasura를 Discourse의 Postgres 데이터베이스에 연결하여 더 맞춤화되거나 범위가 좁아진 FE를 만들 수 있다는 생각을 해본 분이 있나요?

**URL:** <https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576>\
**Category:** Development\
**Created:** [4월 28, 2020, 9:58오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576 "2020-04-28T09:58:17Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dnk8n](https://avatars.discourse-cdn.com/v4/letter/d/bbe5ce/32.png) [@dnk8n](https://meta.discourse.org/u/dnk8n)\
**Post date:** [4월 28, 2020, 9:58오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/1 "2020-04-28T09:58:17Z")

</div>

> **[Hasura: Creator of PromptQL, Data Delivery Network & GraphQL Engine](https://hasura.io/)**
>
> Hasura delivers accurate, fast, and secure data access for AI and digital experiences. Trusted by data leaders and developers at Fortune 100 companies and high-growth AI and digital natives.

_Poll ([view on site](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/1))_

---

<div class="post-metadata">

**Author:** ![ManUtopiK](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manutopik/32/169931_2.png) [@ManUtopiK](https://meta.discourse.org/u/ManUtopiK)\
**Post date:** [5월 19, 2020, 12:08오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/2 "2020-05-19T00:08:31Z")

</div>

재밌네요, 며칠 전 제가 정확히 이렇게 했거든요!

Hasura/nuxt.js를 1년째 다양한 프로젝트에서 사용하고 있습니다.  
Hasura는 매우 강력하고, 예정된 기능들도 매우 기대됩니다!

discourse 포럼을 매우 좋아하지만(Ruby와 Ember는 잘 몰라서요), Hasura를 여기에 적용해 보았습니다.

 ![image](https://global.discourse-cdn.com/meta/original/3X/f/5/f5d32aabaf7330e9b53c74d625dffa5ef67b6dfe.png)

Ruby 개발자가 아니어서 설치가 필요했는데, Mac에서 개발 환경을 설치하는 데 몇 가지 문제가 있었습니다. `cppjieba_rb` gem 때문에 고생하고 있어요…

그래서 결국 [이 덤프](https://meta.discourse.org/t/could-anyone-give-a-database-schema-dump/142749)를 가져와서 PostgreSQL과 Hasura에 설정했습니다.

모든 테이블이 가져온 것 같습니다. 뷰는 하나만 있나요? (badge\_posts)  
모든 외래키 관계도 추적했기 때문에, 다음과 같은 쿼리를 수행할 수 있습니다:

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

```

지금은 여기까지 왔습니다…

---

<div class="post-metadata">

**Author:** ![dnk8n](https://avatars.discourse-cdn.com/v4/letter/d/bbe5ce/32.png) [@dnk8n](https://meta.discourse.org/u/dnk8n)\
**Post date:** [5월 19, 2020, 7:53오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/3 "2020-05-19T07:53:27Z")

</div>

와, 기대되네요. 실환경에서 Hasura 컨테이너를 실행해 보고 결과를 공유하겠습니다. 정보를 교환해 볼 수 있겠네요.

---

<div class="post-metadata">

**Author:** ![dnk8n](https://avatars.discourse-cdn.com/v4/letter/d/bbe5ce/32.png) [@dnk8n](https://meta.discourse.org/u/dnk8n)\
**Post date:** [5월 19, 2020, 8:15오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/4 "2020-05-19T08:15:21Z")

</div>

참고로, 실행 중인 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`

이제 이를 도커화된 postgres(`docker pull postgres:10.12`)에 복원하고 개발을 위해 Hasura에 연결할 수 있습니다(이제 별도의 데이터베이스이므로 읽기 전용 수준에서만 실제로 유용합니다).

프로덕션 수준으로 이를 수행하려면, Discourse가 제공하는 환경을 설정하고 Amazon RDS와 같은 서비스에 데이터베이스를 호스팅해야 합니다. 그러면 해당 데이터베이스에 대한 읽기 및 쓰기 액세스가 용이해집니다.

위 덤프를 로컬에 복원하려면:

1. 도커 네트워크 생성:

```plaintext
docker network create discourse-dev-net

```

1. 첫 번째 셸에서:

```plaintext
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 사용자 생성(덤프에 필요):

```plaintext
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. 복원 수행:

```plaintext
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를 위 설정에 연결하려면:

```plaintext
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을 방문할 수 있습니다)

---

<div class="post-metadata">

**Author:** ![dnk8n](https://avatars.discourse-cdn.com/v4/letter/d/bbe5ce/32.png) [@dnk8n](https://meta.discourse.org/u/dnk8n)\
**Post date:** [5월 19, 2020, 9:31오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/5 "2020-05-19T09:31:35Z")

</div>

상속된 데이터베이스를 직접 다루어 보니, @Falco 님이 [이 게시물](https://meta.discourse.org/t/could-anyone-give-a-database-schema-dump/142749)에서 지적한 내용이 매우 명확하게 드러났습니다.

Postgres의 강력한 기능 중 거의 대부분이 활용되지 않고 있습니다. 로직의 거의 전부가 Ruby 쪽에서 처리되고 있죠.

따라서 제 결론은, 이 접근법 자체가 완전히 도움이 되지 않는다는 것입니다.

다른 방법으로는 Hasura의 [원격 스키마 기능](https://hasura.io/docs/1.0/graphql/manual/remote-schemas/index.html)을 사용하는 것이 있지만, 이를 위해서는 Discourse가 REST가 아닌 GraphQL API를 제공해야 합니다… 따라서 이 역시 자체적으로는 큰 도움이 되지 않습니다.

하지만 [기존 REST API를 GraphQL 레이어로 감싸는](https://hasura.io/blog/create-a-remote-schema-to-wrap-a-rest-api-hasura/) 방법이 있습니다. 이는 위에서 언급한 방법들보다(또는 그것들과 결합했을 때) 더 유망해 보입니다. 해당 기사에서는 [시작할 수 있는 보일러플레이트 코드가 포함된 저장소](https://github.com/hasura/sample-remote-schema)를 안내하고 있습니다.

---

<div class="post-metadata">

**Author:** ![ManUtopiK](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manutopik/32/169931_2.png) [@ManUtopiK](https://meta.discourse.org/u/ManUtopiK)\
**Post date:** [5월 21, 2020, 1:14오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/6 "2020-05-21T01:14:50Z")

</div>

답변해 주셔서 감사합니다.

저는 도커를 아주 잘 다루지는 못하지만, 제 문제는 도커 쪽에 있는 것이 아닙니다. discourse 개발 환경을 설정할 수 없어서 데이터베이스가 없습니다… 그저 이 빈 덤프 파일만 있을 뿐입니다.

어쨌든, 저는 이 덤프를 Heroku 인스턴스에 바로 배포했습니다! 그래서 라이브로 직접 테스트해 보실 수 있습니다 🙂  
[이 온라인 GraphiQL](https://graphiql-online.com/graphiql)에 접속하여 아래 엔드포인트를 설정해 보세요:  
[https://discourse-hasura.herokuapp.com/v1/graphql](https://discourse-hasura.herokuapp.com/v1/graphql)  
자유롭게 조작해 보실 수 있습니다! 관리자 비밀번호가 없으므로 mutation과 subscription도 수행할 수 있습니다…

> [@dnk8n](#):
>
> 거의 모든 로직은 Ruby 쪽에서 처리됩니다.

Hasura에서 discourse를 테스트하면서 제가 발견한 바로는, 모든 커스텀 함수, 트리거, 계산 필드… 모두 Ruby로 정의되어 있습니다. 이식성 측면에서 좋지 않습니다 😕

> [@dnk8n](#):
>
> 다른 접근 방식은 Hasura의 [리모트 스키마 기능](https://hasura.io/docs/1.0/graphql/manual/remote-schemas/index.html)을 사용하는 것이지만, 그렇게 하려면 Discourse가 REST가 아닌 GraphQL API를 가져야 합니다… 따라서 이것만으로는 큰 도움이 되지 않습니다.

큰 도움이 되지 않습니다. discourse GraphQL API가 없기 때문이죠. 하지만 이는 Hasura의 강력한 기능입니다. 저는 Stripe의 커스텀 GraphQL과 함께 이 기능을 많이 사용하고 있습니다. 만약 discourse GraphQL API가 있다면, 리모트 스키마를 통해 우리 자신의 GraphQL에 연결할 수 있을 것입니다!

> [@dnk8n](#):
>
> 하지만 [기존 REST API를 GraphQL 레이어로 감싸는](https://hasura.io/blog/create-a-remote-schema-to-wrap-a-rest-api-hasura/) 방법도 있습니다.

네, 하지만 모든 스키마와 리졸버(resolver)를 직접 구축해야 합니다. 작업량이 상당합니다!  
여기서는 discourse의 Open API를 사용하는 것이 더 나을 것 같습니다: [https://docs.discourse.org/](https://docs.discourse.org/) (다운로드 버튼 참고), 그리고 [https://graphql-mesh.com/docs/handlers/openapi와](https://graphql-mesh.com/docs/handlers/openapi%EC%99%80) 같은 GraphQL 생성기를 함께 사용하면 됩니다.  
가능한 한 빨리 시도해 보겠습니다…

---

<div class="post-metadata">

**Author:** ![ManUtopiK](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manutopik/32/169931_2.png) [@ManUtopiK](https://meta.discourse.org/u/ManUtopiK)\
**Post date:** [5월 21, 2020, 1:58오전 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/7 "2020-05-21T01:58:21Z")

</div>

오, 기대됩니다! graphql-mesh를 시도해 보았습니다.  
하지만 [https://docs.discourse.org/](https://docs.discourse.org/) 의 다운로드 버튼 아래에 있는 openapi 파일이 깨져 있는 것 같습니다 😕  
[여기](https://apitools.dev/swagger-parser/online/#)에서 유효성을 검사해 봤는데, 다음과 같은 오류가 나네요:

```plaintext
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)

```

그래서 discourse API의 다른 openapi나 swagger 파일을 찾아보았습니다. [이것](https://raw.githubusercontent.com/erkist/discourse_swagger/master/discourse_swagger.yml)만 찾았네요.  
426번째 줄이 조금 깨져 있긴 했지만, 제가 직접 수정했습니다.

graphql-mesh를 설정한 후, 작동하는 graphql API를 만들 수 있었습니다! 그런데…  
이 swagger 파일은 불완전하거나 너무 오래된 것 같습니다. 쿼리가 4개뿐이고, mutation은 없으며, user 타입의 속성도 몇 개만 있네요… 😕

discourse의 swagger나 openapi 파일을 구할 수 있는 곳이 있을까요?

---

<div class="post-metadata">

**Author:** ![dnk8n](https://avatars.discourse-cdn.com/v4/letter/d/bbe5ce/32.png) [@dnk8n](https://meta.discourse.org/u/dnk8n)\
**Post date:** [5월 21, 2020, 12:40오후 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/8 "2020-05-21T12:40:11Z")

</div>

> [@ManUTopiK](#):
>
> aphql API를 사용하면 원격 스키마를 가진 자체 GraphQL에 이를 통합할 수 있습니다!

유망해 보이는 작업입니다. 잘하셨습니다! Discourse가 Swagger/OpenAPI와 같은 오픈 스펙을 준수하면 좋겠습니다. 찾고 있는 정보를 찾기를 바랍니다.

지금 이 일에 쓸 시간이 많지 않지만, 나중에 다시 확인해 보겠습니다.

---

<div class="post-metadata">

**Author:** ![gingerman](https://avatars.discourse-cdn.com/v4/letter/g/47e85d/32.png) [@gingerman](https://meta.discourse.org/u/gingerman)\
**Post date:** [5월 29, 2020, 2:02오후 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/9 "2020-05-29T14:02:02Z")

</div>

> [@ManUTopiK](#):
>
> 그래서 discourse API의 다른 openapi 또는 swagger 파일을 검색했습니다. 마침 [이 파일](https://raw.githubusercontent.com/erkist/discourse_swagger/master/discourse_swagger.yml)을 찾았습니다.  
> 426번 줄이 약간 깨져 있었지만, 제가 수정했습니다.
> 
> graphql-mesh를 설정한 후, 작동하는 graphql API를 얻었습니다! 하지만…  
> 이 swagger 파일은 완전하지 않거나 너무 오래되었습니다. 쿼리가 4개뿐이고, mutation은 없으며, user 타입의 속성도 매우 적습니다…

흥미로운 작업이네요. 현재 상태에서 어떤 graphql 쿼리가 가능한지 확인해볼 수 있도록 해당 코드를 어디에 공개해 두셨나요?

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://meta.discourse.org/u/EricGT)\
**Post date:** [5월 29, 2020, 2:31오후 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/10 "2020-05-29T14:31:06Z")

</div>

`기타`로 투표하려고 했는데 작동하지 않았습니다.

---

<div class="post-metadata">

**Author:** ![ManUtopiK](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manutopik/32/169931_2.png) [@ManUtopiK](https://meta.discourse.org/u/ManUtopiK)\
**Post date:** [7월 22, 2021, 12:53오후 UTC](https://meta.discourse.org/t/anyone-thought-of-connecting-hasura-to-discourses-postgres-database-for-a-potentially-more-customised-or-narrowed-down-fe/149576/11 "2021-07-22T12:53:37Z")

</div>

늦게 답변드려 죄송합니다. 질문을 놓쳤습니다.  
네, discourse hasura graphql 엔드포인트로 플레이할 수 있습니다:

> [@ManUtopiK](#):
>
> [이 온라인 graphiql](https://graphiql-online.com/graphiql)로 이동하여 이 엔드포인트를 설정하세요:  
> [https://discourse-hasura.herokuapp.com/v1/graphql](https://discourse-hasura.herokuapp.com/v1/graphql)  
> 플레이해 보세요! 관리자 비밀번호가 없으므로 변형(mutation)과 구독(subscription)도 수행할 수 있습니다…
