ニフティグループ Advent Calendar 2021 の1日目の記事です。
こんにちは。ニフティライフスタイル株式会社でエンジニアをしている kiwi です。 以前は iOS を中心にアプリ開発を担当していましたが、最近は Fargate と戦っています。
はじめに
Webサービスを運営するにあたって切っても切り離せないのが、コンテンツ管理です。
普段プライベートで運営しているサービスは PHP(Laravel)を使って実装していますが、コンテンツ管理には管理者フラグ付きのユーザーだけが入れる画面やフォームを自作していたりしています。
しかし、例えばこのようなブログやお知らせなどは、設計を面倒くさがってHTMLをそのままテキストで格納し、サイトに埋め込んでしまうことが多いです。
自分だけが使う画面なのでそれでも良いのですが、サイトそのものの構成も含めて別のアプローチも知っておきたいところです。 そこで、今回このブログサイトを Gatsby + AWS Amplify で立ち上げてみたので、その内容をご紹介します。
技術選定
新規で、しかも技術検証目的で立ち上げるからには、最近の技術を活用したいところです。今回はSSG + HeadlessCMS による構築にチャレンジしてみることにしました。
SSG するためのフレームワーク候補としては Next.js (React), Nuxt.js (Vue) などがありましたが、手元にたまたま入門書があったこと、また HeadlessCMS との相性が良さそうだったことから、 Gatsby を選択することにしました。
HeadlessCMS の方は、Contentful や Strapi などを検討しました。しかし、業務などでの活用を考えた時に「データを手元に置いておきたい」「柔軟な権限管理をしたい」などの要求がありそうだと感じ、いずれの選択肢も悩ましいという結果に。
どちらのCMSも、コンテンツを投稿した後は GraphQL で取得して表示をすることになります。そこでふと思い出したのが Amplify (backend) でした。業務では AWS を活用していることもあり、この機会に Amplify をガッツリ使ってみるのも良いかなと、バックエンドにも採用することにしました。
Amplify でのサイト(Gatsby)ホスティング
Gatsby のブログサンプルを作成して GitHub にアップロードした後、ドキュメントの記載に沿って、マネジメントコンソールから設定を行いました。
package.json の中身などから、よくあるフレームワークであれば自動的にビルド設定を作ってくれる機能のおかげで、公開するところまではそれほど苦労せずに到達しました。ブログの記事ページに直接アクセスするとトップに飛ばされるという現象が発生したものの、リダイレクト設定を直したら解消したので一安心(参考)。まずは Amplify のドメインで記事が見れるようになりました。
本当はトップページ含めてもう少し見た目を変えたかったのですが、全くその時間が取れず、サンプルの見た目ほぼそのままでの公開となりました。
Amplify による GraphQL 環境
Amplify CLI で操作して push するようなイメージだったのですが、Amplify Admin UI で大体何でもできるので、こちらも GUI 上でおおよそ済ませてしまいました。先程のホスティングとは違い、 CloudFormation で実際に何が作られているかが見れるので安心感があります。
データのモデリングという作業は、今回触れた HeadlessCMS で共通して出てきたのですが、バックエンドの仕様によって少しずつ仕様が違います。Amplify で通常データベースを作成する場合、GraphQL (AppSync) のデータソースとしては DynamoDB が使われます。
そのため、基本のオブジェクトには ID!
型が必須(Partition Key)だったり、ソートが苦手(Global Secondary Indexを張る必要がある)だったりと、DynamoDB ならではの制約がかなり強く出ます。シンプルな要件であればこれでも良さそうですが、様々な条件での絞り込みやソートが必要な場合は、RDB など別のデータベースを検討する必要がありそうです。なお、AppSync は Aurora をはじめとする SQL データベースなどをデータソースとして利用することも可能です。
Amplify によるストレージ構築
さて、ブログとしてもう一つ欠かせない要素が画像です。
この記事は Markdown 形式で記述しているので、画像を載せることも可能なのですが、その画像のホスティング環境を用意しなくてはいけません。
Amplify ではストレージとして S3 バケットを作成でき、アプリケーション内から取得をすることも可能なのですが、Auth (認証)環境のセットアップが必須となっています。
認証環境をセットアップすると、Cognito Userpool および Cognito ID プールが作成されます。いわゆるメールアドレスとパスワードによるユーザー管理基盤を提供するサービスと、そのアカウント情報を使って AWS IAM の一時トークンを発行できるサービスです。
Amplify のストレージサービスは、この IAM トークンを使って、ユーザーがファイルを格納したり、署名付き URL を発行してアクセスしたりするために利用するものになっています。 そのため、アプリケーションのユーザーがアップロードした画像を参照したり、また外部へ公開することも可能なのですが、アクセスするユーザーごとに異なる署名付きの URL が発行されることになり、このような Markdown の記事から参照するのとはちょっと違うかな、ということになります。
ということで今回は仕方なく、自分で CloudFront を立て、そのオリジンとして Storage で作成された S3 (念のため /public 以下のパス)を指定するようにしました。アプローチとして正解なのかよくわかっていないので、詳しい方ぜひ教えてください……。
さいごに
今回は Gatsby と AWS Amplify を使ってブログを作成してみました。記事を公開するためにフロントエンドのビルドが必要だったり、ファイルの取り扱いも少し癖があったり、色々とツッコミどころは満載ですが、ひとまず最低限の要件は満たせているかなと思います。
このブログもまだ生まれたてですし、JavaScript のフレームワークを活用した構成や Amplify についてももう少し学んで、より良い形を模索していきたいと思います。
参考
- Amplify Framework Docs
- Welcome to AWS Amplify – AWS Amplify
- Fastest Static-Site Generation Web Framework | Gatsby
- Build Serverless Blog with Gatsby and AWS Amplify & AppSync – DEV Community
ニフティライフスタイルでは、Webサービスを一緒につくる仲間を募集しています。