トップ / 第5章
CHAPTER 05 DATA
データの読み書き
お知らせ一覧の表示や問い合わせフォームの保存など、データを読み書きする仕組みと、秘密情報の扱い方を学びます。
この章でわかること
- データの置き場所(データベース・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つ選んで「答え合わせをする」を押すと、正誤と解説が表示されます。何度でも選び直せます。
この章の確認問題はすべて回答済みです。間違えた問題は、解説を読んでから本文の該当箇所を見直しておきましょう。