本教程构建一个只有 title、description、completed 三个业务字段的任务 API。功能刻意保持简单,把重点放在输入校验、HTTP 状态码和每一步验证上。
环境:PHP 8.4、Composer、Laravel 12、MySQL 或 SQLite。命令均在新建练习项目中执行。
一、创建项目并启用 API 路由
composer create-project laravel/laravel task-api
cd task-api
php artisan install:api
php artisan about
配置 .env 的数据库连接后先执行 php artisan migrate:status。确认数据库指向练习库,再运行迁移;不要在有重要数据的数据库上使用 migrate:fresh。
二、创建模型与表结构
php artisan make:model Task -m
php artisan make:controller Api/TaskController --api
php artisan make:request StoreTaskRequest
php artisan make:request UpdateTaskRequest
在任务迁移的 up 方法中加入以下字段:
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title', 120);
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->timestamps();
});
运行 php artisan migrate,再用 php artisan migrate:status 确认该迁移状态为 Ran。
三、限定允许批量写入的字段
class Task extends Model
{
protected $fillable = ['title', 'description', 'completed'];
protected function casts(): array
{
return ['completed' => 'boolean'];
}
}
$fillable 防止客户端通过额外字段修改不该修改的数据;布尔转换保证 JSON 响应中的 completed 是真正的布尔值。
四、把校验集中到 Form Request
两个请求类的 authorize() 在练习阶段返回 true。真实项目应在这里或 Policy 中加入权限判断。
// StoreTaskRequest::rules()
return [
'title' => ['required', 'string', 'max:120'],
'description' => ['nullable', 'string', 'max:2000'],
'completed' => ['sometimes', 'boolean'],
];
// UpdateTaskRequest::rules()
return [
'title' => ['sometimes', 'required', 'string', 'max:120'],
'description' => ['sometimes', 'nullable', 'string', 'max:2000'],
'completed' => ['sometimes', 'boolean'],
];
五、实现控制器与资源路由
public function index()
{
return Task::query()->latest()->paginate(20);
}
public function store(StoreTaskRequest $request)
{
$task = Task::create($request->validated());
return response()->json(['data' => $task], 201);
}
public function show(Task $task)
{
return ['data' => $task];
}
public function update(UpdateTaskRequest $request, Task $task)
{
$task->update($request->validated());
return ['data' => $task->fresh()];
}
public function destroy(Task $task)
{
$task->delete();
return response()->noContent();
}
// routes/api.php
Route::apiResource('tasks', TaskController::class);
执行 php artisan route:list --path=api/tasks,应看到 index、store、show、update、destroy 五组动作。
六、用真实请求验证成功与失败
php artisan serve
curl -i -X POST http://127.0.0.1:8000/api/tasks \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"title":"阅读 Laravel 文档"}'
curl -i -X POST http://127.0.0.1:8000/api/tasks \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"title":""}'
第一条请求应返回 201;第二条应返回 422 且包含 errors.title。然后依次验证 GET、PATCH 和 DELETE,删除成功应返回 204。
排错清单
- 404:检查
route:list与 URL 是否包含/api。 - 419:API 路由不应放在依赖 Web CSRF 的表单流程里。
- 500 数据库错误:核对
.env,并执行php artisan config:clear后重试。 - 字段未写入:检查模型
$fillable和请求的validated()输出。