この記事は、スターフェスティバル Advent Calendar 2020の2日目です。 スターフェスティバルではエンジニアを募集しています。
近頃、仕事で扱う技術スタックがPHPからNext.jsやexpress等node.js系へ移行したため、趣味に個人的な学習を兼ねて新たに個人サイトを作ることにしました。
それが以前のブログ記事でも紹介した道の駅メモです。
(こちらは技術的試行を兼ねているのととりあえず要素が強かったためデザインと呼べるレベルの内容をしていないのはご容赦ください…)
技術スタックの移行について詳細はまた後日のAdvent Calenderにて書く予定です。
Next.jsを使うことは決めていましたが、これまで運用していた(このブログが動いている)Wordpressのサーバで共存して動かすのではなく、運用負担などを考え新たにheadless CMSやFaaSを採用することにしました。
こちらで採用しているメインのアプリケーションは以下のようなものです。
- Headless CMS(記事や画像の管理などを行う)
- フロントサイド(Headless CMSで取得した内容の表示等を担う)
Prismic.ioでは、はじめにCustom Typesによりタイトル、本文、各種属性、画像フィールドなどを設定しておくと、APIサーバとして動作し各種アプリケーションに対して記事のコンテンツを各種形式にて出力する役割をしてくれます。
なお、現在Community Planで無料で使うことができます。(詳細)
REST APIは各種言語にてライブラリが用意されており、簡易な手法でjs系各種フレームワークや、PHP、Ruby、Javaなど各種言語から容易に取得することが可能となっています。
ここで私が着目したのはAPIの出力形式としてGraphQLに対応している点です。
GraphQLはデータベースに対してスキーマを定義しクエリを呼ぶことで、使いたい各種ビジネス要件に対して個別にクエリを発行し、フロントエンドより必要なデータのみを取得することができます。
一般的にREST APIを使用した場合、当初は完璧と思ってAPI設計をしたものの、追加した各種ページで表示したい要件が増え、似たような要件を持つendpointが増えがちということがありますが、そのような場合にとりわけGraphQLはマッチしていると言えるでしょう。
またGraphQLを使った場合、SQLで言うSELECT文に相当するフィールド指定には*(すべてのカラム)のような指定ができないため、意図しないテーブルのデータが流出することをロジックレベルで回避することができるかもしれません。(例えば、APIのレスポンスからIPアドレスなどの情報を意図せず出力してしまうことなど)
具体的な文法などの情報については今回の記事では特に触れませんが(この点に関しては各種先行記事が参考になるでしょう)、GraphQLについて煩雑な構築等を避け手っ取り早く体験するため、このPrismicは大きな助けになると思います。
最初にご紹介したサイトでは、Next.jsからPrismic.ioのGraphQL endpointにクエリを発行し、条件に応じた記事一覧や記事情報を取得するということをしています。(なお、後から知ったことでPrismic.ioのGraphQLではグループフィールドにおいてフィールド指定の検索ができず、都道府県ごとの記事検索には別途REST APIを使っています。この場合はタグを使用したほうが良かったらしい…)
Prismic.ioではGraphQLを使う際に、GraphQL API Explorerを使用してコードに組み込む前にクエリのデバッグもできる点も評価できるでしょう。
node.js環境からGraphQLにアクセスするためのクライアントは apollo-client を使っています。
apollo-clientを導入した場合、強力なコードジェネレータを使うことがNext.js/Typescriptの環境において大きな助けになるでしょう。
まずprismicからAPIによりスキーマファイルを取得した上で、必要なクエリをgraphql-tagライブラリのgql文によりcomponentなどのソースコードに記述し、targetやクエリの場所、スキーマファイルを指定しコードジェネレータを使うと、ソースコードと同階層に__generated__ディレクトリが生成され、クエリのレスポンスに対するTypeScriptの型ファイルが自動生成されます。
特に複雑な定義をせずともクエリ文を書くだけで型定義が着くのはすごく便利と感じられる方が多いのではないでしょうか。
とはいえGraphQLにはパフォーマンスを考慮したりスキーマを正しく設計する点が難しかったり、課題は沢山ありそうで、場合によってはREST APIと並行して運用することが必要だったりするかもしれません。
しかし近頃DB migrationやORMなど、実装に難しさを感じる点などについて新たなパッケージが成熟しつつあるように思えます。
今現在すぐにGraphQLが活かせる状況になくても、近い将来手近に活用するシーンが見えて行きているように感じますので、今のうちにできる事から学んでみるのはいかがでしょうか。
(理解しきれていない箇所や間違いなどあるかもしれません、ぜひコメントなどでご指摘ください)