はじめに
Day21 では、
✅ React からログイン
✅ JWT を保存
✅ 認証付き API を呼び出す
ところまで到達しました。
今日はついに、
「ログイン後に何ができるアプリか」
を形にします。
今日のゴール
・投稿一覧 API を Laravel で作成する
・JWT 認証付きで一覧取得できる
・React で投稿一覧を表示する
・「API × SPA」の基本形を完成させる
今回作る機能
・ログイン済みユーザーのみ閲覧可能
・投稿の一覧を取得
・フロントでリスト表示
※ 作成・更新・削除は Day23 以降で実装します
投稿モデルの確認
php artisan make:model Post -m
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body')->nullable();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
php artisan migrate
ルーティング定義
routes/api.php
Route::middleware('auth:api')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
});
コントローラ作成
php artisan make:controller PostController
投稿一覧 API(Laravel)
use App\Models\Post;
public function index()
{
$posts = Post::with('user')
->latest()
->get();
return response()->json([
'status' => 'success',
'data' => $posts
]);
}
なぜ認証必須にする?
・誰でも見られる API にしない
・ログイン後の世界を明確に分ける
・JWT の効果を体感するため
👉 「ログインしないと見られない」
は SPA の基本構造です。
Postman で動作確認
GET /api/posts
Authorization: Bearer xxx.yyy.zzz
レスポンスが返れば成功 🎉
React 側で一覧を取得する
import { useEffect, useState } from 'react';
const Posts = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchPosts = async () => {
const token = localStorage.getItem('token');
const res = await fetch('http://localhost/api/posts', {
headers: {
Authorization: `Bearer ${token}`
}
});
const data = await res.json();
setPosts(data.data);
};
fetchPosts();
}, []);
return (
<ul>
{posts.map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
</li>
))}
</ul>
);
};
export default Posts;
useEffect の役割
useEffect(() => {
fetchPosts();
}, []);
・初回表示時に API を呼ぶ
・無限ループ防止
・SPA の基本パターン
よくあるエラー
❌ 401 Unauthorized
・トークン未送信
・トークン期限切れ
👉 再ログインで解決
❌ posts.map がエラー
Cannot read property 'map'
👉 初期値を [] にしているか確認
表示を少し整える
{posts.length === 0 && <p>投稿がありません</p>}
UX が少し良くなります。
実装のポイント
・API は認証前提
・レスポンス形式を揃える
・フロントは data のみを見る
・ロジックは最小限に
今日のまとめ
・投稿一覧 API を実装した
・JWT 認証付きで取得できた
・React で一覧表示できた
・SPA アプリらしくなってきた
次回 Day23
CRUD が揃います。
Day23 — 投稿作成APIを実装し、Reactから投稿できるようにする
「読むだけ」から「使えるアプリ」へ進みます。