本文目录导读:

遵守PHP RESTful规范涉及多个层面,从URL设计、HTTP方法使用到状态码和响应格式,以下是完整的实践指南:
URL设计规范
使用名词而非动词
// ❌ 错误
GET /api/getUser
POST /api/createUser
GET /api/deleteUser
// ✅ 正确
GET /api/users
POST /api/users
DELETE /api/users/{id}
使用复数形式
// ✅ 推荐 GET /api/products GET /api/orders // ❌ 不推荐 GET /api/product GET /api/order
嵌套资源表示关联
// 获取用户的所有订单 GET /api/users/123/orders // 获取特定用户的特定订单 GET /api/users/123/orders/456
HTTP方法使用
class UserController {
// GET - 获取资源列表
public function index() {
// 获取所有用户
return $this->response($users);
}
// POST - 创建资源
public function store() {
// 创建新用户
return $this->response($newUser, 201);
}
// GET - 获取单个资源
public function show($id) {
// 获取指定用户
return $this->response($user);
}
// PUT/PATCH - 更新资源
public function update($id) {
// 更新用户信息
return $this->response($updatedUser);
}
// DELETE - 删除资源
public function destroy($id) {
// 删除用户
return $this->response(null, 204);
}
}
HTTP状态码使用
class ApiResponse {
// 成功响应
public static function success($data, $status = 200) {
return json_encode([
'status' => $status,
'data' => $data,
'timestamp' => time()
]);
}
// 错误响应
public static function error($message, $status) {
return json_encode([
'status' => $status,
'error' => [
'message' => $message,
'code' => $status
],
'timestamp' => time()
]);
}
}
// 使用示例
public function store(Request $request) {
try {
// 验证数据
if ($request->validate() === false) {
return ApiResponse::error('验证失败', 422);
}
// 创建资源
$user = User::create($request->all());
// 201 Created
return ApiResponse::success($user, 201);
} catch (Exception $e) {
// 500 Internal Server Error
return ApiResponse::error('服务器错误', 500);
}
}
常用状态码
// 2xx 成功 200 OK // 请求成功 201 Created // 资源创建成功 204 No Content // 删除成功,无返回内容 // 4xx 客户端错误 400 Bad Request // 请求格式错误 401 Unauthorized // 未认证 403 Forbidden // 无权限 404 Not Found // 资源不存在 422 Unprocessable Entity // 验证失败 // 5xx 服务器错误 500 Internal Server Error // 服务器内部错误
响应格式规范
// 统一响应格式
{
"status": 200,
"data": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
},
"meta": {
"page": 1,
"per_page": 20,
"total": 100
},
"timestamp": 1642345678
}
// 分页响应
public function index(Request $request) {
$page = $request->get('page', 1);
$perPage = $request->get('per_page', 20);
$users = User::paginate($perPage);
return $this->response(
$users->items(),
200,
[
'page' => $page,
'per_page' => $perPage,
'total' => $users->total()
]
);
}
过滤、排序和搜索
public function index(Request $request) {
$query = User::query();
// 过滤
if ($request->has('status')) {
$query->where('status', $request->get('status'));
}
// 排序
$sortBy = $request->get('sort_by', 'created_at');
$order = $request->get('order', 'desc');
$query->orderBy($sortBy, $order);
// 搜索
if ($request->has('q')) {
$query->where('name', 'like', '%' . $request->get('q') . '%');
}
// 分页
$perPage = $request->get('per_page', 20);
$users = $query->paginate($perPage);
return $this->response($users);
}
认证和授权
// 使用中间件保护API
Route::middleware('auth:api')->group(function () {
Route::apiResource('users', 'UserController');
});
// JWT认证示例
public function login(Request $request) {
$credentials = $request->only('email', 'password');
if ($token = auth()->attempt($credentials)) {
return $this->success([
'access_token' => $token,
'token_type' => 'Bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
return $this->error('认证失败', 401);
}
版本控制
// 使用URL版本控制
Route::prefix('api/v1')->group(function () {
Route::apiResource('users', 'v1\UserController');
});
Route::prefix('api/v2')->group(function () {
Route::apiResource('users', 'v2\UserController');
});
// 或使用请求头版本控制
public function handle(Request $request, Closure $next) {
$version = $request->header('Accept-Version', 'v1');
if ($version == 'v2') {
// 使用v2逻辑
}
return $next($request);
}
错误处理中间件
class ApiExceptionHandler {
public function render($request, Exception $exception) {
if ($request->is('api/*')) {
// 处理404
if ($exception instanceof ModelNotFoundException) {
return $this->error('资源不存在', 404);
}
// 处理验证错误
if ($exception instanceof ValidationException) {
return $this->error('验证失败', 422, $exception->errors());
}
// 处理认证错误
if ($exception instanceof AuthenticationException) {
return $this->error('未认证', 401);
}
}
return parent::render($request, $exception);
}
}
最佳实践总结
/**
* RESTful API 最佳实践检查清单
*
* 1. ✓ 使用正确的HTTP方法
* 2. ✓ 使用复数名词
* 3. ✓ 返回正确的状态码
* 4. ✓ 使用统一的响应格式
* 5. ✓ 支持过滤、排序和分页
* 6. ✓ 使用认证机制
* 7. ✓ API版本控制
* 8. ✓ 缓存策略
* 9. ✓ 速率限制
* 10. ✓ HTTPS
* 11. ✓ 输入验证
* 12. ✓ 错误处理
*/
// 完整的RESTful控制器示例
class UserController extends ApiController {
// GET /api/users
public function index(Request $request) {
$users = User::filter($request)->paginate();
return $this->respondWithPagination($users);
}
// POST /api/users
public function store(CreateUserRequest $request) {
$user = User::create($request->validated());
return $this->respondCreated($user);
}
// GET /api/users/{id}
public function show(User $user) {
return $this->respondWithData($user);
}
// PUT /api/users/{id}
public function update(UpdateUserRequest $request, User $user) {
$user->update($request->validated());
return $this->respondWithData($user);
}
// DELETE /api/users/{id}
public function destroy(User $user) {
$user->delete();
return $this->respondNoContent();
}
}
遵循这些规范可以让你的PHP API更加标准、可维护和易用,记住RESTful不仅仅是URL格式,而是一种API设计理念。