💙

[Fortnite] Nextjs14でちょい真面目にユーザー戦績確認アプリを作った🪅[ビクロイ]

2024/01/10に公開

Fortniteって?🔫

フォートナイトはEpic Gamesから出てる個人的に世界一面白いと思っている神TPSゲームです🔫
詳しくはこちらから💁
https://www.fortnite.com

成果物🧢

デモ
https://youtu.be/zrFelQXkzYM?si=5vGk5rsyYQLx2rLN

アプリはこちら🍀
https://fortnite-victory-royals.vercel.app

https://github.com/tara-is-ok/fortnite-victory-royals

技術スタック🌱

tech stack
今回メインで使った技術

  • Nextjs
    • App Router, API Routes
  • Tailwind CSS + Material Tailwind
    • プロジェクト後半からMaterial Tailwindを使用
  • SWR
    • 状態管理
  • ESLint + Prettier
    • 個人開発といえど最低限の品質を保って開発を行う
    • 以前作成したテンプレートが良い感じに使えるかの確認

選定理由は単純にNextjs14, TailwindCSSを使ってみたかったからです。
こういうことが出来るのも個人開発の良いところだったと感じました!💡

https://zenn.dev/tara_is_ok/articles/75f17beaef6ee8

ディレクトリ構成🧩

/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を参考にディレクトリ構成を考えました

https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md

機能💦

Victory Royal(1位)数の表示

スクショやリンクを送ってただ自慢したかった私個人の超願望🤹‍♂️

ページ画像

wins

戦績表示

  • ソロ、デュオ、スクワッドの各モードに応じた詳細な戦績を表示する
    • ビクロイ数やキル数、勝率などの表示
ページ画像

stats

API Routes(中間API)🫥

今回は下記の構成です!
api routes

本体の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を作成する
https://github.com/tara-is-ok/fortnite-victory-royals/blob/main/src/app/api/stats/route.ts

ここで先にheaderの付与を行う

2. フロントエンドのリクエスト先をAPI Routesに設定
https://github.com/tara-is-ok/fortnite-victory-royals/blob/main/src/hooks/useStats.ts

API Routes側でheadersなどの情報が隠蔽されるため、フロントエンドではAPI Routesのエンドポイントを叩くだけで良くなります

参考

こちらの記事を参考にさせていただきました!🎂
https://zenn.dev/sutamac/articles/624aba9a62c52a

背景🗝️

今回アプリを作成するにあたり大きく分けて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で管理しているのですが、ルート画面遷移時に状態がリセットされる事象に遭遇してハマっています
おそらくこの課題が関連していそうですが、まだ試せていないです。
https://github.com/i18next/next-i18next/issues/2187

Victory Royal(1位)数の表示UIのアップデート

開発をしていていくつかUIのアイデアが思いつきました。
以下はその例です。

  • 進撃の巨人のリヴァイやミカサの討伐数とビクロイ(またはキル数)を比較する
  • ビクロイ数とエベレストの標高を比較する
  • など

煽りパターンが1パターンでは相手(友人)も煽りに慣れてしまうと思うので、今後は煽りパターンを切り替えるようにしてたくさん煽れるように追加で実装していきたいです🪼笑

最後に❤️‍🔥

今回アプリを作成してみて、私はまだ200弱しかビクロイしてないことに気づきました(プレイ歴は3年ほど)
これではまだ胸を張って煽るレベルではないので、ゲーム、仕事ともに精進していきます!!!!

Discussion