Overview
このガイドでは、tanStack Start とMongoDBを使用して最新の Webアプリケーションを構築する方法を説明します。 tanStack Start は、TanStackエコシステムの「TanStack ルーター」や「TanStack クエリ」などのReactライブラリとフロントエンドバックエンド開発を統合するフルスタックフレームワークです。
このチュートリアルのアプリケーションは、次のレイヤーで構成されています。
データベース層: MongoDB はデータを保存および検索します。
サーバー層:tanStack Start は、フロントエンドをMongoDBデータベースに接続するためのAPIエンドポイントとロジックを提供します。
データ管理レイヤー:tanStack クエリは、フロントエンドのサーバーサイドの状態を管理し、データ取得、ロード状態、エラー処理のロジックを統合します。
プレゼンテーション レイヤー: React は、TanStack クエリ データを使用してUIを実装します。
TransStack 起動アプリケーションでMongoDBを使用する理由
MongoDB のドキュメントモデルではデータがJSONのようなドキュメントとして保存されるため、複雑なマッピングなしでJavaScriptオブジェクトを簡単に操作できます。これは、TanStack Start のReactコンポーネントと TypeScript インターフェースと一致します。
tanStack Query は、 MongoDB の応答をキャッシュし、ロード状態を管理し、コンポーネント間でデータを同期することで、データレイヤーを効率的に処理します。これにより、手動の状態管理が不要になり、冗長なデータベース呼び出しが減ります。
この組み合わせは、次の機能を必要とするアプリケーションに適しています。
時間の経過とともに変化する可能性のある柔軟なデータ構造
最小限のクライアント側コードでリアルタイムデータ更新
データベースからUIへの型の安全性
効率的なキャッシュとバックグラウンド データの同期
クイック スタート チュートリアル
このチュートリアルでは、 MongoDBと統合する TransStack Startアプリケーションの作成について説明します。アプリケーションはサンプルレストラン データにアクセスし、その結果をローカルでホストされているサイトに表示します。これには、 MongoDB AtlasでホストされているMongoDBクラスターを接続し、データベースの情報にアクセスして表示する手順が含まれています。
Tip
TransStack Start ではなくNode.jsドライバーを使用してMongoDBに接続する場合は、次のガイドを参照してください: Node.jsドライバーを使い始める
プロジェクトを設定する
このセクションの手順に従って、プロジェクトの依存関係のインストール、Atlas クラスターの作成、アプリケーションディレクトリの設定を行います。
前提条件を確認します
クイック スタートアプリケーションを作成するには、次のソフトウェアがインストールされていることを確認してください。
前提条件 | ノート |
|---|---|
バージョン 20 以降を使用します。 | |
コードエディター | このチュートリアルでは Visual Studio Code を使用しますが、お好みのエディターを使用できます。 |
端末 | MacOS ユーザーの場合は、 ターミナル または 類似アプリを使用します。 Windowsユーザーの場合は、 PowerShell を使用します。 |
MongoDB Atlasクラスターを作成する
MongoDB Atlas は、 MongoDB配置をホストするフルマネージドクラウドデータベースサービスです。 MongoDBデプロイいない 場合は、「 MongoDBを使い始める 」チュートリアルを完了して、無料のクラスター(クレジットカードは不要)を作成します。 MongoDBを使い始めるsample_restaurants では、このチュートリアルで使用される データベースなどのサンプルデータベースをクラスターにロードする方法も説明されます。
クラスターに接続するには、接続 URI を使用する必要があります。接続 URI を取得するには、Atlas ドキュメントの「 クラスターへの接続 」チュートリアルの手順に従います。
Tip
接続 URI を安全な場所に保存します。
プロジェクトのスケルトンを作成する
公式の TransStack Start CLI を使用して、プロジェクトのスケルトンを初期化します。ターミナルを開き、目的のプロジェクトディレクトリに移動します。
初期化コマンドを実行します。
npm create @tanstack/start@latest
構成のプロンプト
インストールウィザードが、セットアップの完了をガイドします。次のオプションを選択します。
Prompt | 入力 | アクション |
|---|---|---|
プロジェクトの名前は何にしますか? | ご希望のプロジェクト名 | 名前を入力し、 Enter キーを押します |
tailwind CSS を使用しますか。 | はい | 「Y」と入力し、 Enter キーを押します |
ツールチェーンを選択します | デフォルト(なし) | [なし] を選択し、 Enter キーを押します |
配置アダプターを選択します | デフォルト:(Unitro) | Enter キーを押します |
プロジェクトにどのような追加オンが必要か? | なし | Enter キーを押します(TanStack クエリは手動でインストールされます) |
例えが必要ですか。 | なし | Enter キーを押します |
インストールが完了したら、プロジェクトディレクトリに移動します。
MongoDBとの互換性のための Vite の構成
tanStack Start はビルド ツールとして Vite を使用します。デフォルトでは 、Vite はブラウザの依存関係をバンドルしようとします。ただし、 Node.jsドライバーはサーバー側のネイティブ モジュールである mongodb-client-encryption に依存しています。これは、ブラウザ環境に対して Vite がバンドルするときにエラーを発生させます。
これを防ぐために、mongodb-client-encryption モジュールを最適化とサーバー側のレンダリングから除外するように Vite を設定します。
プロジェクトルートの vite.config.ts に移動し、内容を次のコードで置き換えます。
import { defineConfig } from 'vite' import { devtools } from '@tanstack/devtools-vite' import { tanstackStart } from '@tanstack/react-start/plugin/vite' import viteReact from '@vitejs/plugin-react' import viteTsConfigPaths from 'vite-tsconfig-paths' import tailwindcss from '@tailwindcss/vite' import { nitro } from 'nitro/vite' const config = defineConfig({ plugins: [ devtools(), nitro(), // this is the plugin that enables path aliases viteTsConfigPaths({ projects: ['./tsconfig.json'], }), tailwindcss(), tanstackStart(), viteReact(), ], optimizeDeps: { // Exclude this server-side dependency to avoid bundling errors exclude: ['mongodb-client-encryption'], }, ssr: { // Ensure this module is externalized during server-side rendering external: ['mongodb-client-encryption'], }, }) export default config
バックエンドの設定
プロジェクト構造を設定したら、このセクションの手順に従ってバックエンドを設定します。
データベース接続の作成
MongoDBクライアント を初期化するための専用の TypeScriptファイルを作成します。
プロジェクトルートで次のコマンドを実行して、ファイル構造を作成します。
mkdir -p src/lib touch src/lib/db.ts
src/lib/db.ts を開き、次のコードを貼り付けます。
import { MongoClient } from "mongodb" // Connection string from the MongoDB atlas dashboard const uri = process.env.MONGODB_URI let connected = false let client: MongoClient export async function connectToDatabase() { if (!uri) { throw new Error("MONGODB_URI is not defined in environment variables") } if (!connected) { try { client = new MongoClient(uri) await client.connect() connected = true } catch (error) { throw new Error(`Failed to connect to database: ${error instanceof Error ? error.message : 'Unknown error'}`) } } return client.db("sample_restaurants") }
このファイルには、 MongoDBクラスターと sample_restaurantsデータベースに接続する connectToDatabase() 関数が含まれています。 sample_restaurantsデータベースには、レストラン名、料理名、地区、住所情報などのフィールドを含む、ニューヨーク市のレストラン データが含まれています。
サーバー関数を作成する
TransStack Start はサーバー関数 を使用して、サーバー上でコードを安全に実行します。データベースクエリを処理するための専用ファイルを作成します。
プロジェクトルートで次のコマンドを実行して、restaurants.tsファイルを作成します。
mkdir -p src/server touch src/server/restaurants.ts
src/server/restaurants.ts を開き、次のコードを貼り付けます。
import { createServerFn } from "@tanstack/react-start" import { connectToDatabase } from "../lib/db" export interface Restaurant { _id: string address: { building: string coord: [number, number] street: string zipcode: string } borough: string cuisine: string name: string restaurant_id: string } // Gets a list of all restaurants from the database export const getAllRestaurants = createServerFn({ method: 'GET'}) .handler(async () => { const db = await connectToDatabase() const restaurants = await db .collection<Restaurant>("restaurants") .find({}) .limit(100) .toArray() return restaurants.map((restaurant) => ({ ...restaurant, _id: restaurant._id.toString(), })) }) // Gets a list of restaurants in Queens with "Moon" in the name export const getRestaurantsByBorough = createServerFn({ method: 'GET'}) .handler(async () => { const db = await connectToDatabase() const restaurants = await db .collection<Restaurant>("restaurants") .find({ borough: 'Queens', name: {$regex: 'Moon', $options: 'i'} // case-insensitive match }) .limit(100) .toArray() // Convert ObjectId to string for client-side serialization return restaurants.map((restaurant) => ({ ...restaurant, _id: restaurant._id.toString(), })) })
このファイルには、getAllRestaurants() と getRestaurantsByBorough() の 2 つの関数が含まれています。この 2 つの関数はMongoDBクラスターをクエリし、要求されたデータを返します。
フロントエンドの設定
データベース層とサーバーレイヤーを設定したら、このセクションの手順に従って、 データ管理層と表示レイヤーを完了します。
ヘッダー コンポーネントを作成する
src/components/Header.tsx に移動し、コンテンツを次のコードで置き換えます。
import { Link } from "@tanstack/react-router" export function Header() { return( <> <nav className="bg-white px-6 py-2 shadow-md"> <div className="flex justify-between items-center gap-8"> <Link to ="/"> <img alt="MongoDB logo" className="h-10 inline" src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png" width="120" height="40" loading="eager" style={{ maxHeight: '2.5rem', width: 'auto' }} /> </Link> <Link to ="/browse" className="text-lime-800 text-lg font-semibold hover:text-green-700"> Browse </Link> </div> </nav> </> ) }
このコンポーネントはレストランの結果の上にある ヘッダーをレンダリングし、参照リンクとロゴが含まれます。これらにより、ルート間を移動できます。
レストラン リスト コンポーネントを作成する
プロジェクトルートから次のコマンドを実行して、RestaurantList コンポーネントを作成します。
touch src/components/RestaurantList.tsx
src/components/RestaurantList.tsx に次のコードを貼り付けてください。
import {Restaurant} from "../server/restaurants" type Props = { restaurants: Restaurant[] } export function RestaurantList({restaurants}: Props) { return ( <div className="overflow-hidden rounded-lg border border-gray-200 shadow-md"> <table className="w-full"> <thead className="bg-gray-50"> <tr> <th className="px-4 py-3 text-left text-sm font-bold text-gray-700">Name</th> <th className="px-4 py-3 text-left text-sm font-bold text-gray-700">Borough</th> <th className="px-4 py-3 text-left text-sm font-bold text-gray-700">Cuisine</th> </tr> </thead> <tbody className="divide-y divide-gray-200"> {restaurants.map((restaurant) => ( <tr key={restaurant._id}> <td className="px-4 py-3">{restaurant.name}</td> <td className="px-4 py-3">{restaurant.borough}</td> <td className="px-4 py-3">{restaurant.cuisine}</td> </tr> ))} </tbody> </table> </div> ) }
このコンポーネントはレストランの表示を処理します。クエリ データはプロパティとして処理され、プロパティはテーブル内に表示されます。
アプリケーションルーティングの構成
src/routes/__root.tsx に移動します。 __root.tsx の内容を次のコードで置き換えます。
import { HeadContent, Scripts, createRootRoute, Outlet } from '@tanstack/react-router' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import '../styles.css' import {Header} from '../components/Header' //Configure TanStack Query Client with cache and retry options const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, // Data stays fresh for one minute retry: 1, // Retry failed requests once retryDelay: 1000 // Wait one second before retrying }, }, }) export const Route = createRootRoute({ component: () => ( <html lang="en"> <head> <HeadContent /> </head> <body> <QueryClientProvider client={queryClient}> <Header /> <main> <Outlet /> </main> </QueryClientProvider> <Scripts /> </body> </html> ), // Handle 404 errors for non-existent routes notFoundComponent: () => { return ( <div className="p-6"> <h1 className="text-2xl font-bold">404 - Page Not Found</h1> <p>The page you're looking for doesn't exist.</p> </div> ) } })
このファイルは、アプリケーション全体を囲むラッパーです。このコードでは QueryClientProvider を使用して、TanStack クエリがデータ状態を管理できるようにします。
ホームページの設定
src/routes/index.tsx に移動します。 index.tsx の内容を次のコードで置き換えます。
import { createFileRoute } from "@tanstack/react-router"; import {useSuspenseQuery} from '@tanstack/react-query' import { RestaurantList } from "../components/RestaurantList"; import { getAllRestaurants } from "../server/restaurants"; export const Route = createFileRoute('/')({ component: Home, pendingComponent: () => ( <div className="p-6 text-gray-500"> Loading restaurants... </div> ), errorComponent: ({error}) => ( <div className="p-6 text-red-600"> <h2 className="text-xl font-bold">Connection Error</h2> <p>{error.message}</p> <p className="text-sm mt-2">Please check your MongoDB connection string in your .env file</p> </div> ), }) function Home() { const{data: restaurants} = useSuspenseQuery({ queryKey:['restaurants'], queryFn: () => getAllRestaurants(), }) return ( <div className="w-full p-6"> <h2 className="text-lg font-semibold p-4">All Restaurants</h2> <RestaurantList restaurants={restaurants} /> </div> ) }
このルートは、Header コンポーネントと RestaurantList コンポーネントを使用して getAllRestaurants() の結果を表示します。
ブラウザ ページの作成
プロジェクトルートから次のコマンドを実行して、browse.tsx ルートを作成します。
touch src/routes/browse.tsx
src/routes/browse.tsx に次のコードを貼り付けてください。
import { createFileRoute } from '@tanstack/react-router' import { useSuspenseQuery } from '@tanstack/react-query' import { RestaurantList } from '../components/RestaurantList' import { getRestaurantsByBorough } from '../server/restaurants' export const Route = createFileRoute('/browse')({ component: BrowsePage, // Display error UI if MongoDB connection or query fails errorComponent: ({ error }) => ( <div className="p-6 text-red-600"> <h2 className="text-xl font-bold">Connection Error</h2> <p>{error.message}</p> <p className="text-sm mt-2"> Please check your MongoDB connection string in your .env file </p> </div> ), }) function BrowsePage() { // Fetch filtered restaurants using TanStack Query // Query includes borough and search term in the key for proper caching const { data: restaurants } = useSuspenseQuery({ queryKey: ['restaurants', 'queens', 'moon'], // Unique cache key for this filtered query queryFn: () => getRestaurantsByBorough(), // Server function with MongoDB filter }) return ( <div className='w-full p-6'> <h2 className='text-lg font-semibold p-4'> Queens Restaurants with "Moon" in the Name </h2> <RestaurantList restaurants={restaurants} /> </div> ) }
このページには、sample_restaurantsデータベースのフィルタリングされたクエリが表示されます。名前に Moon が含まれるクイーンズのすべてのレストランが表示されます。また、Header コンポーネントと RestaurantList コンポーネントも使用します。
注意
サーバーを実行するまで、createFileRoute 行に IDE に赤色の警告が表示されることがあります。これは正常です。 TransStack ルーターは、アプリケーションを初めて npm run dev で実行するときに、ルートに必要な TypeScript タイプの定義を生成します。サーバーが起動すると、警告は消えます。
ファイル構造を確認します
続行する前に、ファイルのツリーが以下の構造と完全に一致していることを確認してください。追加のプロジェクトファイルは無視しても問題ありません。
your-app/ ├─ node_modules/ ├─ public/ ├─ src/ │ ├─ components/ │ │ ├─ Header.tsx <-- Logo and browse link │ │ ├─ RestaurantList.tsx <-- Table that displays results of DB query │ ├─ routes/ │ │ ├─ __root.tsx <-- Application wrapper │ │ ├─ browse.tsx <-- Browse page, holds results of getRestaurantsByBorough() │ │ ├─ index.tsx <-- Home page, holds results of getAllRestaurants() │ ├─ server/ │ │ ├─ restaurants.ts <--- Server functions │ ├─ lib/ │ │ ├─ db.ts <--- Database connection ├─ .env <-- Connection URI
アプリケーションの実行
残りの手順に従ってサーバーを起動し、レンダリングされたレストラン データを表示します。
クイック スタート チュートリアルが完了しました。
これらの手順を完了すると、 MongoDBデプロイに接続し、サンプルレストラン データに対してクエリを実行し、結果をリアルタイムの応答性でレンダリングするtanStack Startアプリケーションが作成されます。
追加リソース
tanStack Start、TanStackエコシステム、 MongoDBの詳細については、次のリソースを表示します。
tanStack Start のドキュメント
tanStack のドキュメント
ノード.jsドライバーのドキュメント

