はじめに
Next.jsやGraphQLを学ぶ機運の高まりがあったので、GWの期間を使ってゆるふわPodcastのWebサイトを作り直してみた。Rails on HerokuなMPA(SPAの対義語としてMulti Pages Applicationと言うらしい)から、Next.jsによるSPA + GraphQL APIという感じ。
ユーザに見える部分( yuru28.com )をNext.js on Vercelで構築し、従来のRailsアプリにはapi.yuru28.comとしてGraphQL APIと管理画面をやってもらうことにした。
フロントエンド(Next.js, Apollo Client, Chakra UI)
`npx create-next-app yuru28-com` してガシガシ作っていくだけ。デフォルトだとただのJSなので、TypeScript対応*1もしておいた。ページごとにSG(静的HTML生成)、SSR(サーバサイドレンダリング)、そしてCSR(クライアントサイドレンダリング、普通のSPA的な)を選択したり組み合わせたりすることができる。今回の要件だとTOPページ以外はSGで構築することが出来た。
後述するGraphQL APIを叩くために、Apollo ClientというGraphQLのライブラリを使用している。Next.jsとApollo Clientを組み合わせる方法は、Apollo公式のブログにわりと丁寧に書いてあった。SG、SSR、CSRそれぞれの場合のApollo Clientの使い方が書いてあるので読んでおくと良さそう。
Getting Started With Apollo Client in Next.js - Apollo Blog
UIフレームワークとしては、プロフィールサイトを作り直したとき*2に素振りしたChakra UIを採用した。Bootstrapを使っても良かったが、今だとChakra UIの方が流行りらしいということでこっちにした。ネイティブでTypeScript対応していたりするおかげで、コーディング時の体験はなかなか良かった印象。Bootstrapのようにクラスを当てていくのではなく、ReactらしくComponentをimportして使っていくので、そのへんがちょっとめんどくさかった。基本的には、公式のドキュメントをざっと見てどういうComponentがあるのかを頭に入れておいて、作りながら良さそうなComponentを使っていくというスタイルで開発を進めた。
GraphQL API
GraphQL APIは、既存のRails製Webサイトに生やした。RailsでGraphQLといえば、graphql-rubyを使うのが定番らしい。公式のドキュメントを流し読みした後、良さげな入門Qiita記事*3があったのでそれにそって基本のAPIを構築してみた。
ひたすらTypeを定義して、fieldを追加し、必要に応じてresolverを書くという作業ゲー。管理画面もNext.jsで作るとなるとMutationとか必要になるけど、一旦はユーザに見えるページだけをNext.js化して管理画面はそのままなので、今回はQuery書くだけだった。ある程度API側が出来た段階で api.yuru28.com にデプロイし、既存の管理画面以外のページを削除した。
何故かGraphQLのAPIのpaginationはCursor-basedでやるものだという先入観があったので、そういう感じでエピソード一覧のAPIを実装してしまったのだけど、普通にOffset-basedでやればよかったなという後悔がある。Cursor-basedでpaginationをやってしまうと、以下のGIF画像のように、常に prev or next のページ遷移しか出来ずに不便。週イチでしか増えないエピソードというデータに対して、cursor-basedなpaginationは明らかに向かない。あとでOffset-basedな感じに作り直そうと思う。
デプロイ
フロントエンドのコードは、Vercelにデプロイしている。特に特別なことはしていないが、GitHub経由でログイン後にリポジトリを指定し独自ドメインまわりの設定をするだけで動いてくれて便利。
サーバサイドのコードは引き続きHerokuで動かしている。
おわりに
GW後半の3日間でサクッと実装することが出来た。ひとまずPodcastのユーザ側に見える部分だけNext.js化したので認証は無いのだが、管理画面もNext.js化してそのあたりの知見を溜めておきたい。Auth0でも使いたいなぁ。
Next.js、Apollo Client、Chakra UI、GraphQLと、新しい技術が盛り沢山だったが楽しくものを作ることが出来た。今後もサイトの改善をしつつ、働き始めてからあんまり出来ていなかった雑なWebアプリ量産なんかもこの技術スタックでやっていきたいなと思っている。