イベント概要
2023年8月2日に「What’s “Next” JS Meetup」と題してバベル社のuhyoさんをお招きしてNext.jsに関する勉強会を開催しました。 その中でタイミーフロントエンドエンジニアのいーふとさん(@redshoga)の講演をイベントレポートにまとめてお届けします。
今回のスピーカー
Server Actionsの概要
※ 2023年8月2日のイベント開催時点での情報であり、将来的に変わる、変わっている可能性があります。
Server Actionsはざっくり説明するとサーバーで動作するコードをあたかもクライアント上に記述できる機能です。コード下部のLikeボタンがクリックされると、propsに渡されているincreateが呼び出され、その中でPrismaのclientが動作します。
クライアントで動作
レンダリング結果
サーバーで動作
送信データ
一つのファイルだけでなく別ファイルで書くことも可能で左側がクライアントで動作、右側がサーバーで動作します。それぞれに”use client” “use server”というディレクティブを書く必要があります。 レンダリング結果を見ると普通のフォームとして動作することがわかります。右側の”createPost” というのが普通のTypeScriptをインポートしているにも関わらず通常のformとして動いてくれる不思議な機能です。 送信データとしては普通のフォームデータです。内部ではACTION_IDがよしなに付与され、良い感じに動作します。
既存のフルスタックTSのアプローチ
ここまでがServer Actionsを踏まえた未来のTypeScriptをイメージした内容だったのですが、現状のフルスタックTypeScriptにはどんなアプローチがあるのかを見ていきます。
よくあるのがスキーマの活用です。概念としてはOpen APIやGraphQLとも一緒だと思います。スキーマAPIの定義ファイルからTypeScriptの型生成を行う。よく見る代表例としてはopenapi-typescriptなどですね。タイミーではopenapi2aspidaというライブラリを使っています。aspidaというライブラリがあってそれに変換してくれるものですね。当然、定義ファイルが必要になりますが、自動生成される仕組みにしてしまえば楽なのかなと思います。
他の例としてはtRPCが今、流行っているのかなと思っています。TypeScriptに特化したRPCでインターフェースを提供するライブラリという解釈です。Next.js、Express、FastifyにインターフェースとしてつけてあげるとあたかもRPCのような感じで書くことが可能になります。フロント側の対応もしっかりしてReactのhookを勝手に提供してくれる優秀なライブラリだったりします。 シリアライズもsuperjsonが用いられており、MapやSetといったオブジェクトをそのまま送ることが出来ます。
クライアントサイド
レンダリング結果
サーバーサイド
送信データ
こちらが実際に書いた例です。 クライアントサイド側にapi.example.hello.useMutationというのがありますが、これがサーバーサイド側のコードを書くと勝手に生成されているような感覚で書くことができる開発者体験のよいライブラリになっています。 シリアライザとしてはsuperjsonが用いられており、内部ではよしなにwrapされているので使用感としてRPCっぽいといった感じのライブラリになります。
ここまでServer Actionsについてと今までのフルスタックTypeScriptをどうやって書いていたのか、という話をしてきましたが、比較するとServer Actionsは圧倒的に手軽です。”use server”と書くだけで動くので手軽です。 シリアライズの方式も微妙に違っていて、レスポンスで返ってくるやつを色々実験しているのですが、JSXとかも実は送れたりします。 Next.js特化で共通のインターフェースみたいな概念ではないので今のところはServer Actionsを書いて、それをNativeAppから呼ぶみたいなことは想定されていないと思います。revalidatePathの様な所謂、Next.jsのキャッシュサービスと併用して使ってねみたいなサンプルコードとかも散見されるので、インターフェースを提供するというよりはやはりNext.jsに特化したRPCといった印象です。
Server Actionsの活用例
Server Actionsを知っている人は似たイメージを持っていると思いますが、Vercel盛り盛りのフルスタック構成ですね。 サーバーのデータベースを触る際はServer ActionsとかAPI Routesとかで書いて、クライアントコードは普通にReactで書くと。Vercelは最近様々なサーバーレスストレージサービスを出しているのでそれらを活用して永続化していきます。 あとはKey-Valueストアとかもあるのでそれらでキャッシングをしてあげるといった感じになります。
もう一つはBFF as Server Actionsのようなイメージですね。BFF as Server Actionsという言葉自体は私が作った造語なのですが、先程の構成ではネイティブアプリケーションからAPIを叩けないですよね。 それをAPIだけVercelから外に出して、VercelのServer Actionsから叩いてあげる、といったことも可能ではないかなと思っています。あとは単純にServer ActionsにすることでJavaScriptが動かない環境でもフォームとタグが動くのでそういったプログレッシブエンハンスメントを主とした活用もあるのではないかなと思います。
まとめ
今回はSever Actionsこんな感じですよ、ということをお伝えしました。とはいえまだアルファ版なのでServer ActionsちゃんとGAされてほしいなと期待を持っています。便利なので使っていきたいという気持ちですね。最近のNext.jsはフルスタック寄りに様々な機能を提供してくれているんですけど、Railsのような規約(レール)がある訳ではないのでその議論は活発になっていくのでないかなというのを個人的に思っています。
ご清聴ありがとうございました。