Laravel 13 RESTful API 设计最佳实践
摘要
本文将介绍使用 Laravel 13 设计 RESTful API 的最佳实践,包括:
- RESTful 设计原则
- 资源路由设计
- 响应格式规范
- 错误处理
- 实战案例
本文适合希望构建高质量 API 的 Laravel 开发者。
1. RESTful 设计原则
1.1 资源命名
1 2 3 4 5
| GET /api/users # 获取用户列表 POST /api/users # 创建用户 GET /api/users/{id} # 获取单个用户 PUT /api/users/{id} # 更新用户 DELETE /api/users/{id} # 删除用户
|
1.2 使用复数形式
1 2 3 4 5 6 7 8 9
| # 推荐 /api/users /api/posts /api/comments
# 不推荐 /api/user /api/post /api/comment
|
1.3 嵌套资源
1 2 3
| GET /api/users/{userId}/posts POST /api/users/{userId}/posts GET /api/posts/{postId}/comments
|
2. 控制器设计
2.1 资源控制器
1
| php artisan make:controller Api/UserController --api
|
2.2 控制器实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller; use App\Http\Resources\UserResource; use App\Models\User; use Illuminate\Http\Request;
class UserController extends Controller { public function index() { $users = User::paginate(); return UserResource::collection($users); } public function store(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:8', ]); $user = User::create($validated); return new UserResource($user); } public function show(User $user) { return new UserResource($user); } public function update(Request $request, User $user) { $validated = $request->validate([ 'name' => 'sometimes|string|max:255', 'email' => 'sometimes|email|unique:users,email,' . $user->id, ]); $user->update($validated); return new UserResource($user); } public function destroy(User $user) { $user->delete(); return response()->noContent(); } }
|
3. 资源响应
3.1 API 资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource { public function toArray($request): array { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at->toIso8601String(), 'updated_at' => $this->updated_at->toIso8601String(), ]; } }
|
3.2 资源集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserCollection extends ResourceCollection { public function toArray($request): array { return [ 'data' => $this->collection, 'meta' => [ 'total' => $this->total(), 'count' => $this->count(), 'per_page' => $this->perPage(), 'current_page' => $this->currentPage(), 'total_pages' => $this->lastPage(), ], ]; } }
|
4. 响应格式
4.1 成功响应
1 2 3 4 5 6 7 8 9 10 11 12 13
| return new UserResource($user);
return UserResource::collection($users);
return (new UserResource($user)) ->response() ->setStatusCode(201);
return response()->noContent();
|
4.2 错误响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| return response()->json([ 'message' => 'Validation failed', 'errors' => [ 'email' => ['The email field is required.'], ], ], 422);
return response()->json([ 'message' => 'Resource not found', ], 404);
return response()->json([ 'message' => 'Unauthorized', ], 401);
return response()->json([ 'message' => 'Forbidden', ], 403);
|
5. 路由设计
5.1 API 路由
1 2 3 4 5 6 7 8 9 10 11
| use App\Http\Controllers\Api\UserController;
Route::apiResource('users', UserController::class);
Route::apiResource('users.posts', PostController::class) ->shallow();
Route::post('users/{user}/avatar', [UserController::class, 'updateAvatar']);
|
5.2 版本控制
1 2 3 4 5 6 7
| Route::prefix('v1')->group(function () { Route::apiResource('users', UserController::class); });
Route::prefix('v2')->group(function () { Route::apiResource('users', UserControllerV2::class); });
|
6. 分页
6.1 基本分页
1 2 3 4 5 6
| public function index() { $users = User::paginate(15); return UserResource::collection($users); }
|
6.2 简单分页
1
| $users = User::simplePaginate(15);
|
6.3 游标分页
1
| $users = User::cursorPaginate(15);
|
7. 过滤与排序
7.1 过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public function index(Request $request) { $query = User::query(); if ($request->has('status')) { $query->where('status', $request->status); } if ($request->has('search')) { $query->where('name', 'like', "%{$request->search}%"); } return UserResource::collection($query->paginate()); }
|
7.2 排序
1 2 3 4 5 6 7 8 9
| public function index(Request $request) { $sort = $request->get('sort', 'created_at'); $order = $request->get('order', 'desc'); $users = User::orderBy($sort, $order)->paginate(); return UserResource::collection($users); }
|
8. 最佳实践
8.1 使用表单请求
1 2 3 4 5 6
| public function store(StoreUserRequest $request) { $user = User::create($request->validated()); return new UserResource($user); }
|
8.2 使用资源类
1 2 3 4 5
| return new UserResource($user);
return $user;
|
9. 总结
RESTful API 设计的最佳实践:
- 资源命名:使用复数形式
- HTTP 方法:正确使用 HTTP 方法
- 响应格式:统一的响应格式
- 错误处理:清晰的错误信息
参考资料