RESTful API #
一、API概述 #
1.1 RESTful设计原则 #
text
RESTful API设计原则
├── 使用HTTP动词
│ ├── GET - 获取资源
│ ├── POST - 创建资源
│ ├── PUT/PATCH - 更新资源
│ └── DELETE - 删除资源
├── 使用名词表示资源
│ ├── /users - 用户资源
│ ├── /posts - 文章资源
│ └── /comments - 评论资源
├── 使用HTTP状态码
│ ├── 200 - 成功
│ ├── 201 - 创建成功
│ ├── 400 - 请求错误
│ ├── 401 - 未认证
│ ├── 403 - 禁止访问
│ ├── 404 - 未找到
│ └── 500 - 服务器错误
└── 返回JSON格式
1.2 API路由 #
php
// routes/api.php
use App\Http\Controllers\Api\UserController;
Route::apiResource('users', UserController::class);
二、API控制器 #
2.1 创建API控制器 #
bash
php artisan make:controller Api/UserController --api
2.2 控制器实现 #
php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::paginate(10);
return response()->json($users);
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
$user = User::create($validated);
return response()->json([
'message' => '用户创建成功',
'data' => $user,
], 201);
}
public function show(User $user)
{
return response()->json($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 response()->json([
'message' => '用户更新成功',
'data' => $user,
]);
}
public function destroy(User $user)
{
$user->delete();
return response()->json(null, 204);
}
}
三、API资源 #
3.1 创建资源类 #
bash
php artisan make:resource UserResource
php artisan make:resource UserCollection
3.2 资源类定义 #
php
// app/Http/Resources/UserResource.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toIso8601String(),
'updated_at' => $this->updated_at->toIso8601String(),
];
}
}
3.3 集合资源 #
php
// app/Http/Resources/UserCollection.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => [
'total' => $this->total(),
'count' => $this->count(),
'per_page' => $this->perPage(),
'current_page' => $this->currentPage(),
'total_pages' => $this->lastPage(),
],
];
}
}
3.4 使用资源 #
php
use App\Http\Resources\UserResource;
use App\Http\Resources\UserCollection;
// 单个资源
public function show(User $user)
{
return new UserResource($user);
}
// 集合资源
public function index()
{
$users = User::paginate(10);
return new UserCollection($users);
}
// 或使用collection方法
public function index()
{
return UserResource::collection(User::all());
}
3.5 条件属性 #
php
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->when($request->user()->isAdmin(), $this->email),
'secret' => $this->when($request->user()->isAdmin(), function () {
return 'secret-value';
}),
$this->mergeWhen($request->user()->isAdmin(), [
'first_name' => $this->first_name,
'last_name' => $this->last_name,
]),
];
}
3.6 关联资源 #
php
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'posts' => PostResource::collection($this->whenLoaded('posts')),
'comments' => CommentResource::collection($this->whenLoaded('comments')),
];
}
四、分页 #
4.1 基本分页 #
php
public function index()
{
$users = User::paginate(10);
return UserResource::collection($users);
}
4.2 分页响应格式 #
json
{
"data": [
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"}
],
"links": {
"first": "http://example.com/api/users?page=1",
"last": "http://example.com/api/users?page=10",
"prev": null,
"next": "http://example.com/api/users?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "http://example.com/api/users",
"per_page": 10,
"to": 10,
"total": 100
}
}
4.3 简单分页 #
php
$users = User::simplePaginate(10);
4.4 游标分页 #
php
$users = User::cursorPaginate(10);
五、响应格式 #
5.1 标准响应 #
php
// 成功响应
return response()->json([
'success' => true,
'message' => '操作成功',
'data' => $data,
]);
// 错误响应
return response()->json([
'success' => false,
'message' => '操作失败',
'errors' => $errors,
], 400);
5.2 辅助方法 #
php
// 返回成功
return response()->success($data, '操作成功');
// 返回错误
return response()->error('操作失败', 400);
// 返回分页
return response()->paginate($paginator);
六、错误处理 #
6.1 异常处理 #
php
// app/Exceptions/Handler.php
public function render($request, Throwable $exception)
{
if ($request->expectsJson()) {
if ($exception instanceof ModelNotFoundException) {
return response()->json([
'message' => '资源未找到',
], 404);
}
if ($exception instanceof ValidationException) {
return response()->json([
'message' => '验证失败',
'errors' => $exception->errors(),
], 422);
}
}
return parent::render($request, $exception);
}
6.2 自定义异常 #
php
throw new \Exception('自定义错误', 400);
// 或使用abort
abort(404, '资源未找到');
七、API版本控制 #
7.1 URL版本控制 #
php
// routes/api.php
Route::prefix('v1')->group(function () {
Route::apiResource('users', Api\V1\UserController::class);
});
Route::prefix('v2')->group(function () {
Route::apiResource('users', Api\V2\UserController::class);
});
7.2 控制器组织 #
text
app/Http/Controllers/Api/
├── V1/
│ └── UserController.php
└── V2/
└── UserController.php
八、API文档 #
8.1 使用Swagger #
bash
composer require darkaonline/l5-swagger
php artisan vendor:publish --provider="L5Swagger\L5SwaggerServiceProvider"
8.2 注释示例 #
php
/**
* @OA\Get(
* path="/api/users",
* summary="获取用户列表",
* @OA\Response(response="200", description="成功")
* )
*/
public function index()
{
// ...
}
九、总结 #
9.1 核心要点 #
| 要点 | 说明 |
|---|---|
| apiResource | API资源路由 |
| JsonResource | JSON资源类 |
| paginate | 分页 |
| response()->json() | JSON响应 |
9.2 下一步 #
掌握了RESTful API后,让我们继续学习 API认证,了解API安全认证!
最后更新:2026-03-28