[Fortnite] Nextjs14でちょい真面目にユーザー戦績確認アプリを作った🪅[ビクロイ]
Fortniteって?🔫
フォートナイトはEpic Gamesから出てる個人的に世界一面白いと思っている神TPSゲームです🔫
詳しくはこちらから💁
成果物🧢
デモ
アプリはこちら🍀
技術スタック🌱
今回メインで使った技術
- Nextjs
- App Router, API Routes
- Tailwind CSS + Material Tailwind
- プロジェクト後半からMaterial Tailwindを使用
- SWR
- 状態管理
- ESLint + Prettier
- 個人開発といえど最低限の品質を保って開発を行う
- 以前作成したテンプレートが良い感じに使えるかの確認
選定理由は単純にNextjs14, TailwindCSSを使ってみたかったからです。
こういうことが出来るのも個人開発の良いところだったと感じました!💡
ディレクトリ構成🧩
/src
は以下のようにしました!
ディレクトリ | 説明 | 用途 |
---|---|---|
app |
Nextjs App Router + API Routes | URLマッピングを行うページコンポーネント |
components |
UIパーツ | ページを横断して使うコンポーネント |
hooks |
アプリ全体で使うカスタムhook | APIリクエストの隠蔽などのページを横断して使うカスタムHook |
providers |
アプリ全体のコンテキスト | SWRやReact.Contextなどルートでラッピングする必要があるコンポーネント |
types |
アプリ全体で使う型 |
types/api にはOpenAPIから自動生成される型を配置し基本ここから型を参照し開発を行う。また、types/ はドメインごとに独自定義が必要な場合ファイルの作成✅ |
utils |
アプリ全体で使う便利関数 | 定数やオブジェクトの整形などの純粋関数。ドメインごとにファイルの作成✅ |
fragments
gitリポジトリを見ていただいた方は分かる通り、コンポーネント配下に/fragments
というディレクトリが存在しています。
/fragments
は コンポーネントやファイル分割のみを行いたい + そのコンポーネントでしか使わない(ページ横断を行わない) パーツ置き場になります。
これはatomic designからコンポーネント設計を行なった際にorganisms
に1度しか使われないコンポーネントが大量発生する問題に対抗する手段となります。
結果、無意識的にコンポーネントや処理が分割統治され、1ファイルあたりの記述量が減り可読性が向上するのと、コンポーネントが単一責任となり保守性も上がります。
参考
下記のbulletproof-reactを参考にディレクトリ構成を考えました
機能💦
Victory Royal(1位)数の表示
- ビクロイ数に応じて煽りエモート(Gif)を表示させる
- user情報をクエリパラメーターで表現する
スクショやリンクを送ってただ自慢したかった私個人の超願望🤹♂️
ページ画像
戦績表示
- ソロ、デュオ、スクワッドの各モードに応じた詳細な戦績を表示する
- ビクロイ数やキル数、勝率などの表示
ページ画像
API Routes(中間API)🫥
今回は下記の構成です!
本体のAPIを隠蔽
中間APIを挟むことで、外部から本体のAPI(fortnite api)にアクセスすることを防ぐことでセキュリティの強化を図りました!💎
中間APIを利用せずにリクエストを行なった場合headers
の値が外部に見えてしまいます。
今回はPublicなAPIなのであまり効果はないですが、今後開発で使用する場合には役立ちそうだなと感じました!
APIエンドポイントの抽象化
フロントエンド ↔️ バックエンドでのAPIエンドポイントを抽象化を行いました。
今回を例に挙げると、中間APIを使わない場合と使う場合のフロントからのリクエストを次に示します
中間APIなし
export const useStats = () => {
const { params } = useStatsParams()
const queryParams =
hasUsername(params) && new URLSearchParams(params).toString()
const { data, error, isLoading } = useSWR<StatsResponse, StatsError>(
//headerを付与して本体(fortnite-api)に直接リクエスト
`${apiBaseUrl}/stats/br/v2?${queryParams}`,
(url: string) =>
axios(url, {
headers: { authorization: apiKey },
}).then((res) => res.data),
)
return { data: data?.data, error, isLoading }
}
apiBaseUrl
はfortnite-apiのエンドポイントです
中間APIあり
1.API Routesを作成する
ここで先にheaderの付与を行う
2. フロントエンドのリクエスト先をAPI Routesに設定
API Routes側でheadersなどの情報が隠蔽されるため、フロントエンドではAPI Routesのエンドポイントを叩くだけで良くなります
参考
こちらの記事を参考にさせていただきました!🎂
背景🗝️
今回アプリを作成するにあたり大きく分けて3つのタイプの動機がありました🧌
1.モチベ
-
ビクロイ数に応じてエモートを表示させて、そのスクショを撮って友人に自慢したい(煽りたい笑🪬)
- または自分の結果がすぐ見れるリンクを送りたい
- スマホで手軽に確認したい
- かわいめのデザインでフォートナイトの統計をみたい!(超主観🫥)
2.使い勝手
- Discordアカウントを経由している
- 普段私はDiscordを使わないのでアプリを開く習慣がなかった
- 統計を見るためにチャット上で
/command~~
と入力が求められることがあり気持ち的なハードルが高い
- エラー後のUI
- user(私)がメッセージを見て問題を解決でき、次の操作に進めるUIではなかった
- epicアカウントのusernameを入力すべきところに、私が普段fortniteで使用しているplaystationのusernameを入力してしまい統計が見れないなんでや!🧎なんてことが結構あった
3.技術
以下を使ってみたかった
- Next.js14
- App Router
- API Routes
- Tailwind CSS
- 以前作ったNextjsテンプレートがいい感じに動くか
今後の課題🪡
下記についてアドバイスやコメントいただけるとありがたいです!!🍄
ルート画面(/)遷移時にリクエストがリセットされる
userの状態をReact.Contextで管理しているのですが、ルート画面遷移時に状態がリセットされる事象に遭遇してハマっています
おそらくこの課題が関連していそうですが、まだ試せていないです。
Victory Royal(1位)数の表示UIのアップデート
開発をしていていくつかUIのアイデアが思いつきました。
以下はその例です。
- 進撃の巨人のリヴァイやミカサの討伐数とビクロイ(またはキル数)を比較する
- ビクロイ数とエベレストの標高を比較する
- など
煽りパターンが1パターンでは相手(友人)も煽りに慣れてしまうと思うので、今後は煽りパターンを切り替えるようにしてたくさん煽れるように追加で実装していきたいです🪼笑
最後に❤️🔥
今回アプリを作成してみて、私はまだ200弱しかビクロイしてないことに気づきました(プレイ歴は3年ほど)
これではまだ胸を張って煽るレベルではないので、ゲーム、仕事ともに精進していきます!!!!
Discussion