この記事はAmplifyアドベントカレンダー21日目の記事です。
こんにちは!オンライン劇場ZAのUXエンジニアをしています、とうようです。
オンライン劇場ZAというのは昨年11月末に開設した、オンライン演劇のためのプラットフォームです。自分はこのオンライン劇場ZAの立ち上げに学生エンジニアとして関わり、現在はそのまま副業として関わらせてもらっています。
そんなつい先日設立一周年を迎えたオンライン劇場ZAは、設立当初からAmplify + Next.jsという技術スタックで作られています。今回の記事は、UXエンジニアという肩書きのもとフロントとバックエンド、どちらの実装にも関わってきた自分が開発開始からの約一年半を振り返ってAmplifyの良かったところ・いまいちだったところを書いていきたいと思います。
なお構成上、技術の深いところまでは立ち入らず、ここまでのを経緯を振り返りながらそれぞれのトピックのさわりだけ触れる形になっています。個別の詳細はもし機会があったら別途記事にしようと思うのでよろしくお願いします。また、似たような内容で今年の9月にAWSDevDayでも登壇しています。プレゼンと文章だとまとめ方も違ってきているので、こちらも参考にしていただければと思います。
最初の技術選定
2020年9月ごろから集められたメンバー。揃った後は早速技術選定から始まりました。基本的には先行して参加することになっていた現テクニカルディレクターが大枠を検討しており、AmplifyとNext.jsを使うことはかなり序盤に決定しました。フロントに関してはシニアレベルの方が参加していたため、自分が最初に関わったのはデータベース周りに関する検討です。
この時に、集まったメンバーがテクニカルディレクター以外全員フロントという特殊事情があったこと、フロントとしてTypeScriptでの開発が決まっていたこと、あとは単純に自分の興味的なところもあってGraphQLをAppSyncで使おうという提案しました。
実際、遡ってみたらこんな形で提案していたみたいです。
Amplifyからデフォルトで生成されるから参考資料が多いし、バックエンドはER図から型に落とし込めばあとはちょっとごにょごにょするだけで済むっぽいし新しい概念とはいってもどの型の何を取りたいのかさえわかってればすぐ書けるようになりそうだしAppSync使うとCognitoとの連携でアカウントの種別によって取れる情報の制限も簡単にできるみたいだから実装コスト結構下がりそう
ここでも少し触れているのですが、認証はAmplifyを使う関係上Cognitoになるため、その認証情報をいかに活用するかというところが肝になります。AppSync+GraphQLでスキーマの設定ファイルにCognito認証によるアクセス制限の条件が書けるため、データベースのアクセスコントロールが技術選定で解決することができたのはかなり大きかったと思います。
自分が最初に立ち向かった認証の壁
最初に自分が担当したのは、ログイン・新規登録周りと全画面に共通するコンポーネントの作成でした。ログイン・新規登録はこの頃の資料だと少し厄介で、というのも、まだAmplifyが出始めの頃だったのであまり実プロダクトでの活用例が出ておらず、参考にできる記事は大抵デザインなどが作り込まれていないチュートリアルレベルのものが多かったからです。そのため、Amplifyが用意してくれているログイン・新規登録UIを使った認証はたくさん出てきたのですが、肝心の見た目を公式コンポーネントを使わずに、処理だけAmplify+Cognitoを借りるといった使い方の参考になるドキュメントがなかなか見つかりませんでした。
この理由から実装については苦戦する部分も多かったのですが、その中でも特に登録認証メールのハンドリングが難しかったです。登録が終わった後に即ログインさせたい、また想定ユーザー層的にリンクを踏むだけで認証が終わる形にしたいという要件だったのですが、そのような機能は用意されておらず、結果的に仕様・デザインを調整して、以下のような流れで落とし所を見出しました。
- 登録認証メールを少し加工して、HTMLでもろもろをパラメータに含めたリンクを仕込む
- リンクの飛び先では裏で登録認証をしつつ、ユーザー側にはパスワードだけ入力すれば通れる画面を用意しておく
- そこで登録認証完了後にログイン処理を走らせることで見た目としては登録完了と同時にログインしているという状況を作る
結果こういう飛び技的ソリューションを使っていたため、SNS認証の部分は工数やスケジュール観点から断念しました。ですが、それでもここを乗り越えることでCognitoというセキュリティの後ろ盾と、比較的使いやすい登録UIの両方を得られたのは良かったと思います。
実際の実装では全ページに共通するところにReactContext.Providerを仕込んで、そこ経由でフロント側に認証処理を共有するようにしました。こうすることで、実装のしやすさは担保しながら、認証の細かいロジックを全てCognitoのライブラリに任せて安全性も担保しています。
その際はこちらの記事を参考にしたので詳しくはリンク先を参考にしてください(その時出ていた、ほぼ唯一のAmplify-UIを使わない記事です)
中間サーバー役のLambda関数
認証まわり・共通コンポーネントの実装を終えた自分は、続いて決済部分を担当することになりました。この段階ではStripeによるクレカ決済のみ対応する予定でした。単純に実装すること自体はそこまで大変ではないのですが、Stripeを安全に使うためには中間サーバー的なAPIを用意する必要があります。多くの記事ではここもNext.jsのAPI作成機能でまかなっていることが多かったのですが、その頃AmplifyはSSR対応も出来たてであまりサーバー上で常に動かしておくといった使い方はできなかったのでここをLambdaに寄せることにしました。
LambdaにはLambdaなりのクセみたいなものもあったのですが、Amplify側から設定することでバックエンドの環境ごとに同じLambdaを作れるというのは魅力でした。また、Amplifyから作れる=ローカルで開発できるということでもあるので、普段慣れたエディタでLambda関数を書けるというのもいいところだったと思います。結果としてその後増えたコンビニ決済や、メールの送信、問い合わせなどさまざまなニーズにこのLambda関数機能が使われることになりました。
公演演出という実装
2020年11月末、ついにリリースされた後は公演の演出実装との戦いになります。柿落としとなった「それでも笑えれば」では独自チャット機能もリリースすることになりました。映像を配信しながら、オリジナルのチャットを提供するというのはなかなかにさまざまな観点で小規模チームにとっては難しい試みでしたが、AmplifyとGraphQLのおかげで無事提供できただけでなく、チャット内に演出を組み込むという試みも後半の公演では実現することができました。
この戦いの中では、Amplifyのバックエンド環境を複数用意できる機能が役に立ちました。元々はPull Requestごとに環境を立ち上げる機能なども活用しようとしていたのですが、そちらはPRの数だけバックエンド環境が構築されてしまい管理コストがバカにならなかったため諦めました。でも最小限の環境はしっかり検証用に用意しておくことで、影響の大きいバックエンド側の変更・さっと確認したいフロントエンド側の変更が本番環境と関係なく検証できたことで、安心して公演本番に向かうことができました。
その後の公演でも、スタンプ機能であったり、公演ページに入る際のローディング、文字化け演出などさまざまなオンラインならではの演出にチャレンジしてきました。これだけ色々してしまうとその実装コストも相当なものになりそうですが、GraphQLのsubscription機能を活用することでフロント側の実装に集中でき、数々の演出を実現することができました。
ちなみに公演実装中に使った技術としてこんな記事も書いています。Amplifyとは関係ないですが、興味があればぜひ。
Amplifyアップデートの罠
しばらく公演が落ち着くとZAは定常改善に入るのですが、そんな中ネックになったのはAmplifyアップデートに対するところでした。例えばNext.js v11対応が発表された直後、アップデートが問題ないか試すために本番とは別環境でNext.js v11を試していた時に起こった問題がありました。どういうことかというと、その操作を行なった後に環境変数がテスト環境側に固定されてしまうというバグを踏み抜いてしまい、AWS側でも起票してもらいながら緊急対応をするということがあったのです。このようにAmplify側はまだまだ激しく開発が動いているので、最新のものに単純に飛びついてしまうと、簡単には気付けないバグを踏み抜くということがあります。
ですが一方で、そういったところにも大胆かつ慎重に挑戦していくことで、以前できなかったことがAmplifyの進化とともに実現できるようになっていくというのは一つAmplifyに向き合う中で楽しいところでもあると思いました。実際に実現方法に悩みつつも、SSRの動作が安定してきたことで実現した動的なOGP機能に関しては以下にまとめています。
リリース前ほどユーザーに直接繋がるところのアップデートにAmplify自体が関わってくることは少なくなってきましたが、これからもその楽しさは忘れずに細かいところを徐々に進化させていこうと考えています。
まとめ
各話題のさわり、特にAmplifyが関わる部分の話に限定したので思いのほかあっさりした記事になってしまいましたが、この記事で少しでもAmplifyでサービス運営をするということに関して伝わることがあれば幸いです。
この中でも随所で触れてきた通りAmplifyは、まだまだ進化の途上にある技術です。2020年のAmplify進化の軌跡という記事を見ると、一年前はこれすらなかったのか、みたいな気持ちになる方も多いのではないでしょうか。
そして今年は、Next.jsへの追従や、ISRの対応(既存のAmplifyプロジェクトで有効にするのはまだできてませんが)、Amplify Studio周りの発表などどんどんと簡単に協力なWebアプリが作れるような発表がされてきました。正直なところ最後の節で述べた通り、まだまだそれに単純に追従するには安定しない部分が多いことから、全てをすぐに試せるわけではありません。それでもこの進化は、否応無しにAmplifyでサービス開発をしている人たちをワクワクさせるものばかりだったのではないでしょうか。
今後もAmplifyと共にZAを進化させていこうと思った年末でした。
おしまい。