第1章から読む →

トップ / 第5章

CHAPTER 05 DATA

データの読み書き

お知らせ一覧の表示や問い合わせフォームの保存など、データを読み書きする仕組みと、秘密情報の扱い方を学びます。

読む目安 15分確認問題 3問

この章でわかること

  • データの置き場所(データベース・API・CMS)
  • Server Actions と Route Handler の役割
  • 環境変数とAPIキーの安全な扱い方

1. データはどこに置かれているか

お知らせの一覧、商品の在庫、問い合わせの内容。サイトで扱うデータは、ページのプログラムとは別の場所に保管するのが一般的です。代表的な置き場所は3つです。

置き場所どんなものか代表的なサービス
データベース大量のデータを表の形で整理して保管する仕組み。Excelの表を、何万行でも速く安全に扱えるようにしたものPostgreSQL、MySQL、Supabase、Neon など
CMS(コンテンツ管理システム)お知らせやブログ記事を、管理画面から非エンジニアでも更新できる仕組みmicroCMS、Contentful、WordPress など
外部サービスのAPI他社のサービスが公開しているデータの窓口決済(Stripe)、地図、天気、生成AI など

API:データをやり取りする「窓口」

API(エーピーアイ)は、プログラム同士がデータをやり取りするための窓口です。銀行の窓口に決まった用紙を出すと、決まった手続きをしてくれるように、APIに決まった形でお願いすると、決まった形でデータが返ってきます。

2. データを「読む」:サーバーコンポーネントで取り出す

App Routerでは、データを読んで表示するのはとてもシンプルです。第4章で学んだサーバーコンポーネントの中で、直接データを取り出せるからです。

// お知らせ一覧ページ(サーバーコンポーネント)
export default async function NewsPage() {
  const news = await getNewsFromDatabase(); // データを取り出す
  return (
    <ul>
      {news.map((item) => <li key={item.id}>{item.title}</li>)}
    </ul>
  );
}

await は「データが届くまで待つ」という意味です。取り出したお知らせを、1件ずつリストにして表示しています。

この処理はサーバー(厨房)で行われるため、データベースの住所やパスワードがブラウザに届くことはありません。完成したHTMLだけが客席に運ばれます。

3. データを「書く」:Server Actions

問い合わせフォームの送信や、管理画面での記事の保存など、データを書き込む処理にはどうすればよいでしょうか。

以前は、まずサーバー側にAPI(窓口)を作り、ブラウザからその窓口にデータを送る、という2段階の作業が必要でした。Next.jsではServer Actions(サーバーアクション)を使うと、フォームのボタンから、サーバー側の処理を直接呼び出せます。

async function saveInquiry(formData) {
  "use server";                       // ← この処理はサーバーで動く
  const email = formData.get("email");
  // 入力内容を確認し、データベースに保存する
}

<form action={saveInquiry}>
  <input name="email" />
  <button>送信する</button>
</form>

"use server" は「この処理はサーバーで実行する」という印です。第4章の "use client" と対になっています。

大切な注意:入力チェックは必ずサーバーで

ブラウザ側の入力チェック(「メールアドレスの形式が正しくありません」など)は、利用者の便利のためのものです。悪意のある人はブラウザを経由せずにデータを送れるので、保存する前にサーバー側でも必ずチェックする必要があります。また、Server Actionsは外部から呼び出せる窓口でもあるため、「ログインしている人だけが実行できるか」の確認も欠かせません。AIにコードを書かせるときは「サーバー側で入力チェックと権限チェックをして」と一言添えましょう。

4. 外部との窓口:Route Handler

画面ではなく、データだけをやり取りする窓口(API)が必要な場面もあります。例えば次のようなケースです。

  • 決済サービスから「支払いが完了しました」という通知を受け取る(これをWebhook=ウェブフックと呼びます)
  • スマホアプリや社内の別システムから、データを取りに来てもらう

こうした窓口は、app/api/payment/route.ts のように route.ts という名前のファイルで作ります。これをRoute Handler(ルートハンドラー)と呼びます。page.tsx が「人が見る画面」なら、route.ts は「プログラムが使う窓口」です。

やりたいこと使うもの
データを読んで画面に表示するサーバーコンポーネント
自分のサイトのフォームからデータを保存するServer Actions
外部のサービスやアプリとデータをやり取りするRoute Handler(route.ts)

5. 秘密の情報と「環境変数」

データベースのパスワードや、外部サービスを使うためのAPIキー(サービスを使うための合鍵のような文字列)は、プログラムの中に直接書いてはいけません。プログラムは共有されたり公開されたりすることがあるからです。

こうした秘密の情報は、環境変数という仕組みで、プログラムとは別に保管します。開発中は、プロジェクトの中の .env.local というファイルに書きます。

# .env.local(このファイルはGitHubなどに上げない)
DATABASE_URL=postgres://…(データベースの住所とパスワード)
STRIPE_SECRET_KEY=sk_…(決済サービスの秘密キー)
NEXT_PUBLIC_SITE_NAME=サンプル商店

最重要:NEXT_PUBLIC_ の付いた名前

名前が NEXT_PUBLIC_ で始まる環境変数は、ブラウザに送られるプログラムに埋め込まれ、誰でも見られる状態になります。サイト名など、公開してよい値にだけ使います。APIキーやパスワードに NEXT_PUBLIC_ を付けるのは、家の合鍵を玄関に貼り出すようなものです。AIが作ったコードでも、ここは必ず確認しましょう。

6. ログイン機能と「ページに入る前のチェック」

会員サイトや管理画面には、ログイン機能(認証)が必要です。パスワードの安全な保管など注意点が多いため、自作せずに専用のサービスや部品を使うのが一般的です(Auth.js、Clerk、Supabase Auth など)。

また、「ログインしていない人が /admin に来たら、ログイン画面へ案内する」といった、ページに入る前のチェックには、proxy.ts というファイルを使います(15系までは middleware.ts という名前でした)。建物の入り口にいる受付係のような役割です。ただし、受付だけに頼らず、データを扱う処理の中でも権限を確認するのが安全な作り方です。

この章のまとめ

  • データの置き場所は、データベース・CMS・外部サービスのAPIが代表的。
  • 読む=サーバーコンポーネント、フォームから書く=Server Actions("use server")、外部との窓口=Route Handler(route.ts)。
  • 秘密の情報は環境変数で管理する。NEXT_PUBLIC_ の付いた値はブラウザから見えるので、秘密を入れない。

確認問題

選択肢を1つ選んで「答え合わせをする」を押すと、正誤と解説が表示されます。何度でも選び直せます。