HasuraとAlgoliaのデータ連携
いまビジネス系のマッチングアプリを作っているのですが、そこでHasuraとAlgoliaの連携をしました。
違う規格のデータベースのデータを同期させることをETL (Extract, Transform, Load)というらしいです。
Hasuraとは
Postgresをバックエンドに、GraphQLを扱えるようになるサービスです。
Algoliaとは
爆速で検索ができるDBエンジンです。Googleの検索みたいに入力している途中から検索結果が返ってきます。
HasuraとAlgoliaを連携させると何がうれしいの?
AlgoliaはNoSQLとしてJSONでデータを格納し、relationalにデータを保存することができません。なのでrelationalなデータはPostgresに保存して、Hasura経由でGraphQLで呼べるようにして、高速で検索したいテーブルだけAlgoliaとPostgresを同期させる事で高速検索を実現します。
GraphQL経由でアプリからINSERTやUPDATEがPostgresに対して行われた場合Hasuraのevent triggerを使ってAlgoliaのデータを更新することでPostgresとAlgoliaのデータの同期を行います。
連携の実際
こちらのHasuraのgithubにGoogle Cloud Functionsでの例がありますね。
このrepoの下の方にデータの流れの説明があります。
このデータの流れを順番に説明すると:
- Browser(アプリ)からデータの入力が行われる
- GraphQLでmutationが発行され、Hasuraの中のPostgresのテーブルに対してINSERTやUPDATE文が発行される
- Hasuraに設定されているevent triggerがGoogle Cloud Functionなどのserverlessのwebhookを起動する
- webhookがHasuraから送られてくる新しいデータを受け取りAlgoliaに更新処理を行う
以下のステップで実装を行います。今回はwebhook用にFirebase Cloud Functionsを使ってみました。
- Hasura consoleからテーブルを作成
- Firebase Cloud Functionsへwebhookのコードをdeploy
- Hasura consoleでevent triggerの設定
- Hasura consoleからテーブルを作成
Hasuraのconsoleから画像にあるようにテーブルを用意します。今回はuserテーブルを同期しています。
このuserテーブルはFirebase Authenticationでログインしたユーザー情報を保存していて各ログインに紐づくuidも保存するようになっています。
2. Firebase Cloud Functionsへwebhookのコードをdeploy
webhookで起動する以下のコードをFirebase Cloud Functionsでdeployします。
addAlgoliaUser()ではINSERT文が発行された時に呼ばれた時に使います。
saveAlgoliaUser()はUPDATE文用でuserテーブルの中にあるuidをunique keyとして使ってAlgoliaのusers index内の特定のobjectIDを特定してそれを使ってsaveObject()に渡しています。
この例ではasync/awaitを使っているのでFirebaseのnodeのバージョンを8にあげておいてくださいね。
/functions/package.json 内に以下を追加
"engines": {
"node": "8"
},
deploy後addAlgoliaUserとsaveAlgoliaUserの入ったURLが発行されるのでそれを後で使います。
URLはFirebaseのconsoleから確認できます。
3. Hasura consoleでevent triggerの設定
Hasura Consoleに入り”EVENTS”ページからtriggerを設定します。この例ではINSERT文が発行された時に起動するaddAlgoliaUserへのwebhookを使って設定しています。
テーブルは先ほど用意したuserテーブル。”webhook URL”にdeployしたaddAlgoliaUserの入ったURLを追加して”Create”をクリックしておしまいです。
これでHaruraのGraphQLでuserテーブルに対してmutationを発行した際にAlgoliaと同期できるようになりました!