LS-Finder

LS-Finderの作り方

LS-Finderの作り方

こんにちは、開発担当です。

記念すべきブログ第1回は、LS-Finder が どんな構成で動いているのか という話です。 LS-Finder は、FINAL FANTASY XIV(FFXIV)の Lodestone 公開情報をもとに、キャラクターや コミュニティ(FC / CWLS / LS / PvP)を検索できる支援サイトです。私は新生エオルゼアの頃から プレイしているヒカセンなのですが、本職はバックエンドエンジニアでして、「LS 探しがもっと 楽にならないかな」という自分の欲望に技術で応えた結果がこのサイトです。今日はその裏側を、 システム構成図を交えて紹介します。

全体の構成

LS-Finder は大きく分けて「画面(フロントエンド)」「API(バックエンド)」「データ収集(ワーカー)」 「データベース」の4つで構成され、すべて Render.com 上にホスティングしています。 データの大元は FFXIV 公式の Lodestone です。パーティで言えば、タンク・ヒーラー・DPS ならぬ 「見せる係・答える係・集める係・覚える係」の4人編成ですね。

ユーザー(ブラウザ)PC / スマートフォンフロントエンド(apps/web)React + TypeScript / Render Static SiteAPI(apps/api)Node.js / REST API・Render Web ServicePostgreSQLRender Managed Postgresワーカー(apps/worker)Node.js + got + cheerio / Background WorkerLodestoneFFXIV 公式の公開情報HTTPSREST API(/users, /communities …)SQL で参照収集データを保存定期的にスクレイピング
図: LS-Finder のシステム構成と、データが流れる向き

各コンポーネントの役割

フロントエンド(apps/web)

みなさんが実際に触れる画面です。React + TypeScript で作っており、Vite でビルドして Render の Static Site として配信しています。キャラクター検索・コミュニティ検索・各情報画面・ コミュニティ数ランクなどの UI を提供し、表示に必要なデータは後述の API から取得します。

API(apps/api)

フロントエンドからのリクエストを受け取り、データベースを参照して JSON で返す REST API です。 GET /usersGET /communities といったエンドポイントを提供します。Node.js 製で、 Render の Web Service として動いています。本職がバックエンドなもので、ここは一番の 得意分野です。

ワーカー(apps/worker)

LS-Finder の心臓部とも言える、データ収集を担うバックグラウンドワーカーです。Node.js に got(HTTP クライアント)と cheerio(HTML パーサ)を組み合わせ、Lodestone の公開ページを 定期的に巡回(スクレイピング)して、キャラクターやコミュニティの情報・コミュニティ数の統計などを データベースへ書き込み続けます。みなさんがエオルゼアで冒険している間も、こいつは黙々と ギャザラーのように情報を採集しています。働き者です。

データベース(PostgreSQL)

ワーカーが収集したデータの保存先であり、API が参照する読み取り元でもあります。Render の Managed Postgres を利用しています。「収集(書き込み)」と「閲覧(読み取り)」を分けることで、 みなさんの検索は常に保存済みのデータに対して高速に行えます。

データの流れ

  1. ワーカー が Lodestone を定期的に巡回し、最新のキャラクター・コミュニティ情報を取得する
  2. 取得した情報を整形して PostgreSQL へ保存する
  3. ユーザーが画面で検索すると、フロントエンドAPI にリクエストを送る
  4. APIPostgreSQL を参照し、結果を JSON で返す
  5. フロントエンド が受け取った結果を一覧や詳細画面として表示する

このように「収集する仕組み」と「見せる仕組み」を分離しているため、みなさんの検索体験を 損なわずに、裏側でコツコツとデータを最新化し続けられます。リテイナーに任せた獲得物が いつの間にか揃っているような、そんなイメージで受け取ってもらえれば大体合っています。

技術スタック

  • 言語: TypeScript(フロント・API・ワーカーすべて)
  • フロントエンド: React + Vite、i18n(日本語 / 英語)対応
  • API: Node.js
  • ワーカー: Node.js + got + cheerio
  • データベース: PostgreSQL
  • ホスティング: Render.com(Static Site / Web Service / Background Worker / Managed Postgres)

おわりに

今日は LS-Finder の裏側を紹介しました。役割ごとにシンプルなコンポーネントへ分けた、 素直な構成で動いています。今後もこのブログで、機能追加や運用の裏側をゆるゆると 紹介していく予定です。

それではよい旅を!