[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