响应类型与资源路由
High Contrast
Dark Mode
Light Mode
Sepia
Forest
1 min read208 words

响应类型与资源路由

Laravel 控制器能返回多种类型的响应:JSON、重定向、Blade 视图、文件下载、流式响应。资源路由的 7 个标准方法(index/create/store/show/edit/update/destroy)是 RESTful 设计的骨架。


响应类型速查

// 1. JSON 响应(API 开发最常用)
return response()->json(['data' => $tasks], 200);
return response()->json(['error' => 'Not found'], 404);
// 2. HTTP 状态码快捷方法
return response()->json($task, 201);    // 201 Created
return response()->noContent();          // 204 No Content(DELETE 成功)
// 3. Blade 视图响应(传统 Web 应用)
return view('tasks.index', ['tasks' => $tasks]);
return view('tasks.show', compact('task'));  // compact() 等价于 ['task' => $task]
// 4. 重定向
return redirect('/tasks');
return redirect()->route('tasks.index');
return redirect()->back();                              // 重定向回上一页
return redirect()->route('tasks.show', $task)
->with('success', '任务创建成功!');  // 带 flash 消息
// 5. 文件下载
return response()->download(storage_path('exports/report.pdf'), '报告.pdf');
return response()->file(storage_path('invoices/001.pdf'));  // 浏览器内打开
// 6. Stream 响应(大文件、CSV 导出)
return response()->stream(function () {
$handle = fopen('php://output', 'w');
fputcsv($handle, ['ID', 'Title', 'Status']);
Task::lazy()->each(function ($task) use ($handle) {
fputcsv($handle, [$task->id, $task->title, $task->status]);
});
fclose($handle);
}, 200, [
'Content-Type'        => 'text/csv',
'Content-Disposition' => 'attachment; filename="tasks.csv"',
]);
// 7. 流式 JSON(大数据集,避免内存溢出)
return response()->streamJson([
'tasks' => Task::lazy(),
]);

资源控制器:7 个标准方法

# 创建资源控制器
php artisan make:controller TaskController --resource --model=Task
// app/Http/Controllers/TaskController.php
// Route::resource('tasks', TaskController::class) 自动映射的 7 个方法:
class TaskController extends Controller
{
// GET /tasks           → index()   显示列表
public function index()
{
$tasks = Task::where('user_id', auth()->id())->paginate(20);
return TaskResource::collection($tasks);
}
// GET /tasks/create    → create()  显示创建表单(Web 用,API 不需要)
public function create()
{
return view('tasks.create');
}
// POST /tasks          → store()   处理创建
public function store(StoreTaskRequest $request)
{
$task = Task::create($request->validated() + ['user_id' => auth()->id()]);
return new TaskResource($task);
}
// GET /tasks/{task}    → show()    显示单条
public function show(Task $task)
{
$this->authorize('view', $task);  // Policy 检查
return new TaskResource($task);
}
// GET /tasks/{task}/edit → edit()  显示编辑表单(Web 用)
public function edit(Task $task)
{
$this->authorize('update', $task);
return view('tasks.edit', compact('task'));
}
// PUT/PATCH /tasks/{task} → update() 处理更新
public function update(UpdateTaskRequest $request, Task $task)
{
$this->authorize('update', $task);
$task->update($request->validated());
return new TaskResource($task);
}
// DELETE /tasks/{task} → destroy() 处理删除
public function destroy(Task $task)
{
$this->authorize('delete', $task);
$task->delete();
return response()->noContent();
}
}

只暴露部分路由

// 只要 index 和 show(只读 API)
Route::apiResource('categories', CategoryController::class)->only(['index', 'show']);
// 排除 create 和 edit(API 不需要表单页)
Route::apiResource('tasks', TaskController::class)->except(['create', 'edit']);
// 嵌套资源路由(任务下的评论)
Route::apiResource('tasks.comments', TaskCommentController::class);
// 生成:
// GET    /tasks/{task}/comments          → index
// POST   /tasks/{task}/comments          → store
// GET    /tasks/{task}/comments/{comment}→ show
// PATCH  /tasks/{task}/comments/{comment}→ update
// DELETE /tasks/{task}/comments/{comment}→ destroy

单一行为控制器

有些操作不适合 CRUD 模式——比如"完成任务"、"发送邀请"。单一行为控制器更语义化:

php artisan make:controller CompleteTaskController --invokable
// app/Http/Controllers/CompleteTaskController.php
class CompleteTaskController extends Controller
{
public function __invoke(Task $task)
{
$this->authorize('update', $task);
$task->update(['status' => 'done', 'completed_at' => now()]);
event(new TaskCompleted($task));
return new TaskResource($task);
}
}
// 路由注册(使用 __invoke 的控制器直接写类名)
Route::patch('/tasks/{task}/complete', CompleteTaskController::class)
->name('tasks.complete');

统一 API 响应格式

// app/Http/Resources/TaskResource.php(API Resource)
use Illuminate\Http\Resources\Json\JsonResource;
class TaskResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id'          => $this->id,
'title'       => $this->title,
'description' => $this->description,
'status'      => $this->status,
'priority'    => $this->priority,
'due_date'    => $this->due_date?->toDateString(),
'created_at'  => $this->created_at->toISOString(),
// 条件性包含(只在加载了关联时才包含)
'user'        => new UserResource($this->whenLoaded('user')),
'tags'        => TagResource::collection($this->whenLoaded('tags')),
// 条件性字段(只对有权限的用户返回)
'cost'        => $this->when(
auth()->user()?->isAdmin(),
$this->estimated_cost
),
];
}
}

下一章Eloquent ORM:模型、关联与查询——路由和控制器是 HTTP 层,Eloquent 是数据层。模型的查询作用域、关联预加载、软删除——这些是 Eloquent 进阶使用的核心。