はじめに
Day22 では、
✅ 投稿一覧 API
✅ React で一覧表示
を実装しました。
今日はついに、
「データを作る」= Create
を実装します。
今日のゴール
・投稿作成 API を Laravel で実装する
・認証ユーザーに紐づいた投稿を保存する
・React から投稿を送信できる
・投稿後に一覧へ反映される
今回作る機能
・ログインユーザーのみ投稿可能
・タイトル・本文を送信
・投稿者は自動的に認証ユーザー
ルーティング定義
routes/api.php
Route::middleware('auth:api')->group(function () {
Route::post('/posts', [PostController::class, 'store']);
});
PostController に処理を追加
use Illuminate\Http\Request;
use App\Models\Post;
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'body' => 'nullable|string',
]);
$post = Post::create([
'title' => $request->title,
'body' => $request->body,
'user_id' => auth('api')->id(),
]);
return response()->json([
'status' => 'success',
'data' => $post
], 201);
}
なぜ user_id をフロントから受け取らない?
❌ フロント送信
{
"user_id": 999
}
👉 なりすまし可能
✅ サーバで決定
'user_id' => auth('api')->id()
Post モデル設定
protected $fillable = [
'title',
'body',
'user_id',
];
Postman で動作確認
POST /api/posts
Authorization: Bearer xxx
{
"title": "新しい投稿",
"body": "本文です"
}
React 側:投稿フォーム
import { useState } from 'react';
const PostForm = ({ onCreated }) => {
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
const token = localStorage.getItem('token');
const res = await fetch('http://localhost/api/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
},
body: JSON.stringify({ title, body })
});
const data = await res.json();
if (data.status === 'success') {
setTitle('');
setBody('');
onCreated(data.data);
}
};
return (
<form onSubmit={handleSubmit}>
<input
placeholder="タイトル"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<textarea
placeholder="本文"
value={body}
onChange={(e) => setBody(e.target.value)}
/>
<button type="submit">投稿</button>
</form>
);
};
export default PostForm;
投稿後に一覧を更新する
const [posts, setPosts] = useState([]);
const addPost = (newPost) => {
setPosts([newPost, ...posts]);
};
<PostForm onCreated={addPost} />
UX 的に良いポイント
・投稿後リロード不要
・即座に一覧へ反映
・SPA らしい操作感
よくあるエラー
❌ 422 Validation Error
・title 未入力
・文字数オーバー
👉 フロントで表示改善すると良い
❌ 401 Unauthorized
・トークン期限切れ
・Authorization ヘッダー忘れ
実装のポイント
・認証ユーザーに必ず紐づける
・バリデーションは必須
・レスポンス形式を揃える
・フロントは成功だけを見ればOK
今日のまとめ
・投稿作成 API を実装した
・認証ユーザーの投稿を保存できた
・React から投稿できた
・CRUD の「C」が完成した
次回 Day24
いよいよ CRUD 完成です。
Day24 — 投稿編集・削除APIを実装し、権限制御を入れる
「誰でも編集できる」を防ぎます。