自己紹介と会社のプロダクト紹介

岡本秀高氏(以下、岡本):ここからは、CDKとWebサイト・Webアプリ構築の話にフォーカスしてやっていこうと思います。

自己紹介です。Stripe Inc.のデベロッパーアドボケイトをやっている岡本と申します。ただ、StripeよりもCDKのウェイトのほうが8割ぐらい占めるイメージなので、Stripeの話を集中的に聞きたかった方はちょっとごめんなさい。また別のイベントでよろしくお願いします。

まず会社について簡単に紹介します。Stripeはインターネット向けの決済インフラなどを提供する会社で、いわゆる決済フォームだけではなく、サブスクリプションやCtoCのマーケットプレイス、請求書や税金の自動計算などを日本で提供しています。

売りとしては、ノーコードでも、少ないコードでも決済フォーム、決済リンクが作れることです。より便利に使うには、どうしてもサーバー側の処理が必要になります。

というのも、サブスクリプション請求のデータなどがサーバー側で生成する仕組みになっているので、クライアント側だけでStripe.jsとSDKを使ったり支払いリンクを生成するものを使えます。

(スライドを示して)しかし、機能面の制限があって、右側に出ているコンビニ決済をサポートする場合や、クーポンコードの入力、消費税の自動計算。あとはその人専門の動的なカスタマイズしたプランを作りたい場合も、クライアント側だけではできないようになっています。

そのため、Stripeをアプリに組み込む場合、フロントエンドのReact、Angular、Vueなどを使ったアプリケーションだけではなく、サーバー側の処理も必要になるイメージです。

Next.jsとは何か

React、JavaScriptを使っている方だと、ファーストチョイスに挙がるのが、おそらくNext.jsかなと思っています。Next.jsを知らない方に簡単に紹介すると、Reactを使ったフレームワークです。特徴は、フロントエンドだけではなく、バックエンドのREST APIについてもNext.jsが作ったアプリの中でビルドも管理もできて、モノレポにする必要がなくなります。

さらに、ファンクショナリティとして、サーバーサイドのレンダリングやHTMLの静的な生成、もしくは画像の最適化などについても対応しています。

というところで、Webアプリだけではなく、メディアサイトや通販サイトなど、Reactが使われている案件では、かなり幅広い用途で導入が増えています。

(スライドを示して)コードのイメージはこちらです。下の6行ぐらいを見てもらうと、大方見慣れたReactになっているかなと思います。

(Next.jsとの)違いはgetStaticProps、getServerSidePropsというメソッドを生やすことで、その中で静的にビルドする際、もしくはサーバー側でレンダリングする際に、裏側でAPIを叩いてデータを取ってきて、その中身をReactのコンポーネントの中にpropsとして渡せるようになっています。

このあたりを使うことで、WordPressもしくはmicroCMSなどで作ったブログを静的にして、サイトを速くすることをしている方もいます。

APIもかなりExpressに近く、また少しLambdaにも近いような書き方になっています。リクエストとレスポンスを引数で受け取るので、その中身を使ってコードを書いて、レスポンスのオブジェクトでステータスコードやJSONを返すイメージになっています。

(スライドを示して)アプリを作った場合に、ではどこにデプロイするのかという話になると、初めに選ばれるのは、VercelというNext.jsの提供元かなと思います。AWSではAmazon S3とCloudFrontを使う方法もあるし、Netlifyという静的サイトのホスティングに特化したホスティングサービスもあります。

それ以外には、AWS Amplifyや、今回紹介するserverless-next.jsというプラグインを使ってLambda@Edgeにデプロイしたり。Node.jsのDockerコンテナとして扱いたい場合は、App Runnerを使うなどの方法も考えられるかなと思います。

AmplifyではなくCDKを採用した理由

(スライドを示して)CDK(の話)に入る前に、「Next.jsだったらAmplifyでいいのではないか」というコメントは絶対にもらうと思ったので、そこにだけ少し触れます。個人的な意見では、簡単にNext.jsのアプリをAWSでホストしたい、なおかつサーバー側の面倒を見たくないということであれば、AWS Amplifyを使うほうが圧倒的に簡単です。

その理由は、GUI、Amplify Consoleの中で設定がかなりでき、ビルドのワークフローやステージングと本番などはそれぞれのビルドを行うこともできるので、そのあたりは使い勝手がいいと思います。

また、Amplify Studioを使うことでFigmaのデータを読み込めるので、フロントエンドに特化している方々、もしくはそういう会社にはすごく向いているのかなと思います。

ただ、Amplify CLIが対応していないAWSのサービスに接続したい場合、もしくは設定したい値がある場合などは、管理画面、CLIでできないことが発生します。個人的にはIAM周りがあまり向いていないように感じたので、あまりAmplify Consoleは使っていません。

Amplify Consoleで書いてあるものをGUIでやるのではなくて、コードで管理してGitでコミットしておきたい方は、AmplifyではなくCDKを使うほうがよいかなと思います。

serverless-nextjsプラグインは、AWSでサーバーレスにNext.jsを使う場合に利用をおすすめしているプラグインです。内容は、AWSでこのプラグインがサーバーレス、Lambda、S3などのリソースをよしなに作ってくれるコンストラクタライブラリだと思ってもらうといいと思います。

デプロイするものはCloudFront、Lambda@Edge、S3、SQS(Simple Queue Service )などです。はじめはServerless Componentとして出てきたものでしたが、今はAWS CDKのコンストラクタ、v2に対応したものもあるので、Serverless Framework、Serverless Componentを使ってデプロイするか、AWS CDKを使うかのどちらかになるかなと思います。

CDKの書き方とserverless-nextjsについて

(スライドを示して)CDKの書き方です。こちらについてもかなり書きやすくなっていて、NextJSLambdaEdgeというコンストラクタをインポートして、それを設定するだけです。

(スライドを示して)右側の画像が、開発元が出しているアーキテクチャの画像です。かなりのいろいろなリソースを内部でよしなに出してくれます。

表側に立てるためのCloudFront、静的にビルドしたものや画像のデータなどをホストするためのS3だけではなく、Next.jsがAPIやサーバー側の処理を実行する場合に、必要な実行環境をどこに用意するのかというと、CloudFrontにLambda@Edgeを設定して使います。

フルフルにNext.jsの機能を使おうとすると、今のところは4つのLambda@Edgeがデプロイされます。また、Next.jsにアクセスした後に裏側でキャッシュを更新するISR(Incremental Static Regeneration)という仕組みがあって、そちらを実行するためにSQSをデプロイしたり、IAMやCloudWatch Logsなど、先ほどのこのわずか数行のコードでかなりいろいろなものをデプロイできます。

(スライドを示して)(serverless-nextjsを)使う上での注意点は、Lambda@Edgeをフルフルに使う実装なのでNodeのランタイムのバージョンが、通常のLambdaより少しアップデートが遅くなっている時もあったりすることです。そのあたりに気をつけてください。

あとは、実行時間の制限や、環境変数をLambda@Edgeで設定できない部分や、CloudWatch LogsがCloudFrontにアクセスされて、一番近いEdge LocationでLambda@Edge実行されると思います。

そのリージョンのCloudWatch Logsにログが記録される性質があるので、エラーログの集約などをしたい場合、SentryやRollbarを使うほうがいいかなと思います。

それから、VercelはNext.jsの開発をしているところがリリースしているので、新機能が出た時に真っ先に対応してくれますが、これもコミュニティのプラグインなので、若干の時間差が発生することもご了承ください。

(次回に続く)