定义后端特定的架构细节:
src/
├── routes/ # API路由
├── services/ # 业务服务
├── middleware/ # 中间件
├── entities/ # TypeORM实体
└── lib/ # 工具库
// routes/users.ts
export const userRoutes = new Hono()
.use('*', authMiddleware)
.get('/', async (c) => {
const { page, limit } = c.req.query();
const users = await userService.getUsers({
page: page ? parseInt(page) : 1,
limit: limit ? parseInt(limit) : 20
});
return c.json(users);
})
.get('/:id', validationMiddleware(userSchema.idParam, 'param'), async (c) => {
const { id } = c.req.valid('param');
const user = await userService.getUserById(id);
return c.json(user);
});
// entities/User.entity.ts
@Entity('users')
export class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ unique: true })
email: string;
@Column()
password: string;
@BeforeInsert()
@BeforeUpdate()
async hashPassword() {
if (this.password) {
this.password = await bcrypt.hash(this.password, 12);
}
}
}
// services/GenericCRUDService.ts
export abstract class GenericCRUDService<T extends BaseEntity> {
constructor(protected repository: Repository<T>) {}
async findAll(query: any): Promise<{ data: T[]; total: number }> {
const [data, total] = await this.repository.findAndCount({
skip: (query.page - 1) * query.limit,
take: query.limit,
});
return { data, total };
}
}
sequenceDiagram
participant Client as 客户端
participant Middleware as 认证中间件
participant Redis as Redis
participant Service as 用户服务
Client->>Middleware: 请求携带JWT
Middleware->>Middleware: 解析JWT令牌
Middleware->>Redis: 检查令牌是否在黑名单
Redis-->>Middleware: 返回检查结果
alt 令牌有效
Middleware->>Service: 根据用户ID获取用户信息
Service-->>Middleware: 返回用户数据
Middleware-->>Client: 认证通过,继续处理
else 令牌无效或过期
Middleware-->>Client: 返回401错误
end
// middleware/auth.ts
export const authMiddleware = createMiddleware(async (c, next) => {
const authHeader = c.req.header('Authorization');
if (!authHeader?.startsWith('Bearer ')) {
return c.json({ error: 'Unauthorized' }, 401);
}
const token = authHeader.slice(7);
try {
// 检查Redis黑名单
const isBlacklisted = await redis.get(`blacklist:${token}`);
if (isBlacklisted) {
return c.json({ error: 'Token revoked' }, 401);
}
// 验证JWT
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string };
c.set('userId', decoded.userId);
await next();
} catch (error) {
return c.json({ error: 'Invalid token' }, 401);
}
});