# 路由格式规范

## 核心原则

**统一使用伪静态（Clean URL），禁止 `?action=` 参数路由。**

### 为什么

| `?action=` 模式 | 伪静态模式 |
|---|---|
| 一个路由承载多个功能 | 每个功能独立路由 |
| 中间件无法精细化 | 路由组统一绑定中间件 |
| 日志/监控无法区分操作 | 精确到每个 URL 的 QPS/延迟 |
| SEO/收录不可控 | 每个页面独立收录 |
| Controller 一个 handler 吃所有，变胖 | 每个 handler 单一职责 |

### 对照

```
❌ /auth?action=register          ✅ /auth/register
❌ /auth?action=login             ✅ /auth/login
❌ /posts?action=view&id=1        ✅ /posts/1
❌ /posts?action=list             ✅ /posts
❌ /posts?action=list&topic=go    ✅ /topic/go
❌ /users?action=profile&id=42    ✅ /users/42
❌ /admin?action=theme            ✅ /admin/theme
```

## 路由分层

```
前端页面路由（模板渲染）  →  router/web.go
API 路由（JSON 响应）     →  router/api.go
后台路由                  →  router/admin.go
```

## 格式约定

### 资源路由

| 路由 | 方法 | 说明 |
|---|---|---|
| `/posts` | GET | 帖子列表 |
| `/posts/create` | GET | 发帖页面 |
| `/posts` | POST | 创建帖子（API） |
| `/posts/:id` | GET | 帖子详情 |
| `/posts/:id/edit` | GET | 编辑页面 |
| `/posts/:id` | PUT | 更新帖子（API） |
| `/posts/:id` | DELETE | 删除帖子（API） |

### 认证路由

| 路由 | 说明 |
|---|---|
| `/auth/register` | 注册页 |
| `/auth/login` | 登录页 |
| `/auth/logout` | 登出 |
| `/auth/verify-email` | 邮箱验证 |
| `/auth/forgot-password` | 忘记密码 |
| `/auth/reset-password` | 重置密码 |

认证路由统一挂 `NoIndex` 中间件，禁止搜索引擎收录。

### 用户路由

| 路由 | 说明 |
|---|---|
| `/users/:id` | 用户主页 |
| `/users/:id/posts` | 用户发布的帖子 |
| `/users/:id/comments` | 用户发表的评论 |
| `/settings` | 个人设置 |

### 话题路由

| 路由 | 说明 |
|---|---|
| `/topics` | 话题/板块列表 |
| `/topics/:slug` | 话题详情（该话题下的帖子） |

### 后台路由

| 路由 | 说明 |
|---|---|
| `/admin` | 后台首页 |
| `/admin/users` | 用户管理 |
| `/admin/posts` | 内容管理 |
| `/admin/topics` | 板块管理 |
| `/admin/theme` | 主题切换 |
| `/admin/settings` | 系统设置 |

### 静态资源

```
/static/css/*  →  当前激活主题的 static/css/
/static/js/*   →  当前激活主题的 static/js/
/static/img/*  →  当前激活主题的 static/img/
```

不随路由变化，由 `theme/resolver.go` 统一处理。

## 路由组中间件

```go
// 认证路由：限流 + 禁止收录
authGroup := r.Group("/auth")
authGroup.Use(middleware.RateLimiter(5, 60), middleware.NoIndex)

// 需要登录的路由
authRequired := r.Group("/")
authRequired.Use(middleware.AuthRequired)

// 后台路由：需要管理员
adminGroup := r.Group("/admin")
adminGroup.Use(middleware.AuthRequired, middleware.AdminOnly)

// API 路由
apiGroup := r.Group("/api")
apiGroup.Use(middleware.RateLimiter(60, 60))
```
