128 lines
5.4 KiB
Markdown
128 lines
5.4 KiB
Markdown
# 3.7 路由注册
|
||
|
||
:::tip 概述
|
||
全部 API 路由定义在 `routes/api.php` 中。**公开接口(无需认证)放在中间件组外面**,认证接口统一绑定 `auth.jwt + tenant + demo + log.operation` 中间件组。
|
||
:::
|
||
|
||
## 路由文件位置
|
||
|
||
```text
|
||
routes/api.php
|
||
```
|
||
|
||
## 文件结构(来自项目实际代码)
|
||
|
||
```php
|
||
<?php
|
||
|
||
use App\Http\Controllers\Api;
|
||
use Illuminate\Support\Facades\Route;
|
||
|
||
/*
|
||
|--------------------------------------------------------------------------
|
||
| API Routes
|
||
|--------------------------------------------------------------------------
|
||
|
|
||
| 公开接口放在 middleware 组外面,天然排除认证。
|
||
| 认证接口统一使用 auth.jwt + tenant + demo + log.operation 中间件。
|
||
| demo 位于 log.operation 之前:演示模式下被拦截的请求不写操作日志。
|
||
|
|
||
*/
|
||
|
||
// ===== 公开接口(无需认证)=====
|
||
Route::post('login', [Api\AuthController::class, 'login']);
|
||
Route::post('refresh', [Api\AuthController::class, 'refresh']);
|
||
Route::get('captcha', [Api\CaptchaController::class, 'generate']);
|
||
Route::post('oauth2/token', [Api\AuthController::class, 'token']);
|
||
Route::get('oauth2/check/token', [Api\AuthController::class, 'checkToken']);
|
||
|
||
// ===== 认证接口 =====
|
||
Route::middleware(['auth.jwt', 'tenant', 'demo', 'log.operation'])->group(function () {
|
||
|
||
// --- 登出 ---
|
||
Route::post('logout', [Api\AuthController::class, 'logout']);
|
||
|
||
// --- 个人中心 ---
|
||
Route::get('index/getUser', [Api\IndexController::class, 'getUser']);
|
||
|
||
// ... 其他业务路由
|
||
});
|
||
```
|
||
|
||
## Example 模块路由(来自项目实际代码)
|
||
|
||
```php
|
||
// routes/api.php(认证中间件组内)
|
||
|
||
// --- 案例演示 ---
|
||
Route::get('example/page', [Api\ExampleController::class, 'page']);
|
||
Route::get('example/list', [Api\ExampleController::class, 'list']);
|
||
Route::get('example/detail/{id}', [Api\ExampleController::class, 'detail']);
|
||
Route::post('example/add', [Api\ExampleController::class, 'add']);
|
||
Route::put('example/update', [Api\ExampleController::class, 'update']);
|
||
Route::delete('example/delete/{id}', [Api\ExampleController::class, 'delete']);
|
||
Route::delete('example/batchDelete', [Api\ExampleController::class, 'batchDelete']);
|
||
Route::get('example/export', [Api\ExampleController::class, 'export']);
|
||
Route::post('example/import', [Api\ExampleController::class, 'import']);
|
||
```
|
||
|
||
## 路由格式说明
|
||
|
||
```php
|
||
Route::HTTP方法('路径', [控制器类::class, '方法']);
|
||
```
|
||
|
||
| HTTP 方法 | 用途 | 路径格式 | 示例 |
|
||
|-----------|------|----------|------|
|
||
| GET | 查询 | `{模块}/page`、`{模块}/detail/{id}` | `GET /api/example/page` |
|
||
| POST | 新增/导入 | `{模块}/add`、`{模块}/import` | `POST /api/example/add` |
|
||
| DELETE | 批量删除 | `{模块}/batchDelete` | `DELETE /api/example/batchDelete` |
|
||
| PUT | 修改 | `{模块}/update` | `PUT /api/example/update` |
|
||
| DELETE | 删除 | `{模块}/delete/{id}` | `DELETE /api/example/delete/1` |
|
||
|
||
:::tip 路径参数风格
|
||
本项目统一使用 Laravel 标准 `{id}` 路径参数;批量删除使用 `batchDelete` 路径且为 **DELETE** 方法(请求体仍传 `ids` 数组——本项目 DELETE 接口携带 body)。前缀 `/api` 由 `bootstrap/app.php` 的 `withRouting(api: ...)` 默认前缀统一添加。
|
||
:::
|
||
|
||
## 标准路由模板
|
||
|
||
每个业务模块通常包含以下 9 条路由(全部放在认证中间件组内):
|
||
|
||
```php
|
||
// --- 模块名 ---
|
||
Route::get('{模块}/page', [Api\XxxController::class, 'page']); // 分页列表
|
||
Route::get('{模块}/list', [Api\XxxController::class, 'list']); // 全量列表(可选)
|
||
Route::get('{模块}/detail/{id}', [Api\XxxController::class, 'detail']); // 详情
|
||
Route::post('{模块}/add', [Api\XxxController::class, 'add']); // 新增
|
||
Route::put('{模块}/update', [Api\XxxController::class, 'update']); // 修改
|
||
Route::delete('{模块}/delete/{id}', [Api\XxxController::class, 'delete']); // 删除
|
||
Route::delete('{模块}/batchDelete', [Api\XxxController::class, 'batchDelete']); // 批量删除
|
||
Route::get('{模块}/export', [Api\XxxController::class, 'export']); // 导出(可选)
|
||
Route::post('{模块}/import', [Api\XxxController::class, 'import']); // 导入(可选)
|
||
```
|
||
|
||
## 中间件组说明
|
||
|
||
| 别名 | 类 | 职责 |
|
||
|------|-----|------|
|
||
| `auth.jwt` | `Authenticate` | JWT 解析、`#[Permission]` 反射鉴权、用户信息注入 |
|
||
| `tenant` | `ResolveTenant` | 租户上下文解析与注入 |
|
||
| `demo` | `DemoMiddleware` | 演示模式拦截写操作(`#[DemoAllow]` 放行) |
|
||
| `log.operation` | `LogOperation` | 操作日志采集(响应后落库) |
|
||
|
||
跨域 `Cors`、强制 JSON `ForceJsonResponse`、真实 IP `ProxyMiddleware` 前置于 **API 中间件组**(`bootstrap/app.php` 的 `$middleware->api(prepend:)`),对全部 `/api` 请求生效,无需在路由上声明。演示模式 `DemoMiddleware`(别名 `demo`)位于认证路由组内(tenant 与 log.operation 之间)。详见 [附录 F 中间件执行顺序](/zh/appendix/middleware.html)。
|
||
|
||
:::warning 公开接口放组外
|
||
`login` / `refresh` / `captcha` / `oauth2` 等公开接口**必须放在中间件组外面**(如上例),不要在中间件内部做排除——这是项目的路由约定。
|
||
:::
|
||
|
||
## 验证路由注册
|
||
|
||
```bash
|
||
# 查看所有已注册路由(含中间件与方法名)
|
||
php artisan route:list
|
||
|
||
# 测试路由是否正确(需先登录获取 token,见 2.7 第一个接口调试)
|
||
curl http://localhost:8000/api/example/page -H "Authorization: Bearer <token>"
|
||
```
|