FaunaDBを使ってServerlessでGraphQLクライアントアプリを作る

プロトタイピングなどで、それなりに動作するGraphQL Serverをサクッと作るには良さそうと思ったので、FaunaDBというServerlessなデータベースサービスを紹介します。

FaunaDBについて

FaunaDBは、データベースとしてはガチなやつで、Spannerなどと同じくACID特性を持ちつつスケーラビリティも備えた分散データベースに属するものです。そのアーキテクチャは2012年に発表されたCalvinの論文からインスパイアされているということです。ちなみにSpannerの論文がGoogleから発表されたのもまた2012年のことでした。この辺の歴史や両者の違いについては以下のブログ記事が詳しいです。

Spanner vs. Calvin: Distributed Consistency at Scale

さて、そんなFaunaDBの凄さについては置いておいて、FaunaDBが持つGraphQLのインターフェイスに注目してみましょう。FaunaDBのサービスは何年も前からあるようですが、GraphQLのインターフェイスに対応したのは最近のようです。

The world’s best serverless database, now with native GraphQL

ざっとトピックを拾ってみると以下のような機能があることがわかります。

  • Automatic Index Creation: 自動的にIndexが生成される
  • The @relation directive: Collectionのリレーションを定義できる
  • The @unique directive: フィルドのUnique制約を付けられる
  • Pagination support: Queryの結果をページネーションできる
  • User-defined Resolvers: リゾルバを独自で定義できる(faunaのshellを書く感じでしょうか)

Mutationのロジックを書けないので複雑なことはできないですが、シンプルなCRUD操作なら良さそう、といった感じでしょうか。

サンプルアプリケーション

サンプルアプリケーションとして、チュートリアルのスキーマ定義を利用してシンプルなTODOアプリを作ってみました。

※ なぜかgifに変換したら色が変になってしまいました。

アプリケーションの実装は特筆すべき事がないので割愛します。興味があればソースコードを見てみてください。

https://github.com/bisque33/react-native-web-with-fauna

セットアップ

まずは、fauna.com にFreeプランでSignUpします。

そしてチュートリアルに従って進めていきます。

Get started with GraphQL

FaunaDBではGraphQLのschema定義から自動的にCollection(テーブルに該当するもの)とIndexを生成します。以下のスキーマ定義はチュートリアルにあるものですが、このスキーマ定義ファイルをFaunaDBのコンソールにインポートします。

type Todo {
   title: String!
   completed: Boolean
}

type Query {
   allTodos: [Todo!]
   todosByCompletedFlag(completed: Boolean!): [Todo!]
}

そうして生成されたGraphQLの定義(query/mutation)はFaunaDBのコンソールのGraphQL Playgroundから確認することができます。

インポートしたスキーマ定義ファイルのQueryにはシンプルに戻り値の型を書いているだけなのに、実際のQueryにはPagenationやSizeを指定するフィールドが追加されてたり、Mutationにいったては何も定義していないのにCreate/Update/Deleteが勝手に生成されています。

もちろんスキーマ定義ファイルにより生成されたCollectionは、従来のshellでも操作できます。

partial-update-mutation

自動で生成されたUpdateのMutationのInput typeは、更新対象のtypeと全く同じフィールドを持ちます(Optionalも同じです)。今回は、Todoを完了させるためcompletedフィールドのみを更新したいのですが、titleフィールドが必須になっていてできません。

そこで利用できるのは partial-update-mutation という機能です。これは、Input typeのフィールドがすべてOptionalなUpdate Mutationを提供してくれます。

※ 2019/11/29時点では、まだpreview段階の機能なので、利用するには 有効化 が必要です。具体的には、GraphQLのリクエストヘッダーに X-Schema-Preview: partial-update-mutation を追加します。

これでcompletedフィールドのみを更新することができるようになりました。

api key

コンソール以外からGraphQLに接続するためにはAPI Keyが必要になります。コンソールの Databases > SECURITY > NEW KEY から新しいキーを発行して、HTTPヘッダーに authorization: 'Bearer {API KEY}' を指定します。

おわりに

サーバ側の実装なしにGraphQLサーバとクライアントアプリを作ることができました。GraphQLがインターフェイスになっているとデータベース特有のシェルやSDKを学ばなくてもやりたいことがサクサクできるのがいいですね!MutationのCustom Resolverもサポートされたらもっとできることが広がりそうです。

爆速の開発ツールを手に入れてガンガンプロトタイピングしていきましょう 💪