294 lines
5.6 KiB
Markdown
294 lines
5.6 KiB
Markdown
# Rust Blog Backend
|
||
|
||
基于 **Rust + Actix-web + SQLite** 的博客后端 API 服务。
|
||
|
||
## 特性
|
||
|
||
- 用户注册/登录 (JWT 认证)
|
||
- 博客文章 CRUD (创建、读取、更新、软删除)
|
||
- 图片上传 (支持 jpg/png/webp,含文件类型校验)
|
||
- 分页查询
|
||
- 请求限流 (Rate Limiting)
|
||
- SQLite 数据库 (WAL 模式,高性能)
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
blog_backend/
|
||
├── .env # 环境配置 (不提交到 Git)
|
||
├── .env.example # 配置模板
|
||
├── Cargo.toml # 依赖清单
|
||
├── migrations/ # 数据库迁移文件
|
||
├── uploads/ # 上传文件存储目录
|
||
├── postman_collection.json # Postman 测试集合
|
||
└── src/
|
||
├── main.rs # 入口:HTTP 服务器启动
|
||
├── config.rs # 配置加载
|
||
├── db.rs # 数据库连接池
|
||
├── error.rs # 统一错误处理
|
||
├── models/ # 数据模型 (User, Post)
|
||
├── dtos/ # 请求/响应结构体
|
||
├── repository/ # 数据库操作层
|
||
├── handlers/ # API 控制器
|
||
├── middleware/ # JWT 中间件
|
||
└── utils/ # 工具函数 (密码哈希、JWT)
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
### 1. 环境要求
|
||
|
||
- Rust 1.70+
|
||
- SQLite 3
|
||
|
||
### 2. 安装依赖
|
||
|
||
```bash
|
||
# 安装 sqlx-cli (可选,用于数据库迁移管理)
|
||
cargo install sqlx-cli --no-default-features --features sqlite
|
||
```
|
||
|
||
### 3. 配置环境变量
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
编辑 `.env` 文件:
|
||
|
||
```env
|
||
DATABASE_URL=sqlite:./blog.db
|
||
JWT_SECRET=你的密钥至少32个字符
|
||
BIND_ADDR=127.0.0.1:8080
|
||
RUST_LOG=debug
|
||
```
|
||
|
||
### 4. 运行
|
||
|
||
```bash
|
||
# 开发模式
|
||
cargo run
|
||
|
||
# 生产构建
|
||
cargo build --release
|
||
strip target/release/blog_backend # 可选:减小体积
|
||
./target/release/blog_backend
|
||
```
|
||
|
||
## API 接口
|
||
|
||
### 认证
|
||
|
||
| 方法 | 路径 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| POST | `/api/auth/register` | 用户注册 | 否 |
|
||
| POST | `/api/auth/login` | 用户登录 | 否 |
|
||
|
||
**注册/登录请求:**
|
||
```json
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "password123"
|
||
}
|
||
```
|
||
|
||
**响应:**
|
||
```json
|
||
{
|
||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||
"user": {
|
||
"id": "uuid",
|
||
"email": "user@example.com"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 文章
|
||
|
||
| 方法 | 路径 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| GET | `/api/posts` | 获取文章列表 (分页) | 否 |
|
||
| GET | `/api/posts/:id` | 获取单篇文章 | 否 |
|
||
| POST | `/api/posts` | 创建文章 | 是 |
|
||
| PUT | `/api/posts/:id` | 更新文章 | 是 |
|
||
| DELETE | `/api/posts/:id` | 删除文章 (软删除) | 是 |
|
||
|
||
**分页参数:**
|
||
```
|
||
GET /api/posts?page=1&limit=10
|
||
```
|
||
|
||
**创建文章请求:**
|
||
```json
|
||
{
|
||
"title": "文章标题",
|
||
"content": "文章内容",
|
||
"published": true
|
||
}
|
||
```
|
||
|
||
**分页响应:**
|
||
```json
|
||
{
|
||
"data": [...],
|
||
"page": 1,
|
||
"limit": 10,
|
||
"total": 100,
|
||
"total_pages": 10
|
||
}
|
||
```
|
||
|
||
### 文件上传
|
||
|
||
| 方法 | 路径 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| POST | `/api/upload` | 上传图片 | 是 |
|
||
|
||
**请求:** `multipart/form-data`,字段名 `file`
|
||
|
||
**限制:**
|
||
- 支持格式:jpg, jpeg, png, webp
|
||
- 最大大小:5MB
|
||
- 包含 Magic Number 校验防止伪装文件
|
||
|
||
**响应:**
|
||
```json
|
||
{
|
||
"filename": "uuid.jpg",
|
||
"url": "/uploads/uuid.jpg"
|
||
}
|
||
```
|
||
|
||
### 静态文件
|
||
|
||
| 路径 | 说明 |
|
||
|------|------|
|
||
| `/uploads/*` | 访问上传的文件 |
|
||
|
||
## 认证说明
|
||
|
||
需要认证的接口,请在请求头中添加:
|
||
|
||
```
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
## 限流规则
|
||
|
||
| 接口类型 | 限制 |
|
||
|----------|------|
|
||
| 全局 | 60 请求/分钟 |
|
||
| 认证接口 | 5 请求/分钟 |
|
||
| 上传接口 | 5 请求/分钟 |
|
||
|
||
## 部署
|
||
|
||
### 1. 构建发布版本
|
||
|
||
```bash
|
||
cargo build --release
|
||
strip target/release/blog_backend
|
||
```
|
||
|
||
### 2. 复制文件到服务器
|
||
|
||
```bash
|
||
scp target/release/blog_backend user@server:/opt/blog/
|
||
scp .env.example user@server:/opt/blog/.env
|
||
scp -r migrations/ user@server:/opt/blog/
|
||
```
|
||
|
||
### 3. 服务器配置
|
||
|
||
```bash
|
||
# 创建目录
|
||
mkdir -p /opt/blog/uploads
|
||
|
||
# 编辑配置
|
||
vim /opt/blog/.env
|
||
```
|
||
|
||
生产环境 `.env`:
|
||
```env
|
||
DATABASE_URL=sqlite:./blog.db
|
||
JWT_SECRET=生产环境强密钥至少32字符
|
||
BIND_ADDR=0.0.0.0:8080
|
||
RUST_LOG=warn
|
||
```
|
||
|
||
### 4. Systemd 服务
|
||
|
||
创建 `/etc/systemd/system/blog.service`:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=Rust Blog Backend
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=www-data
|
||
WorkingDirectory=/opt/blog
|
||
ExecStart=/opt/blog/blog_backend
|
||
Restart=always
|
||
RestartSec=5
|
||
Environment=RUST_LOG=warn
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
启动服务:
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable blog
|
||
sudo systemctl start blog
|
||
sudo systemctl status blog
|
||
```
|
||
|
||
### 5. Nginx 反向代理 (可选)
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name blog.example.com;
|
||
|
||
location / {
|
||
proxy_pass http://127.0.0.1:8080;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
}
|
||
|
||
location /uploads {
|
||
alias /opt/blog/uploads;
|
||
expires 30d;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 测试
|
||
|
||
导入 `postman_collection.json` 到 Postman 进行 API 测试。
|
||
|
||
测试流程:
|
||
1. 运行 **Register** 或 **Login** (自动保存 Token)
|
||
2. 运行 **Create Post** (自动保存 Post ID)
|
||
3. 测试其他接口
|
||
|
||
## 技术栈
|
||
|
||
| 组件 | 技术 |
|
||
|------|------|
|
||
| Web 框架 | Actix-web 4 |
|
||
| 数据库 | SQLite + SQLx |
|
||
| 认证 | JWT (jsonwebtoken) |
|
||
| 密码哈希 | Argon2 |
|
||
| 限流 | actix-governor |
|
||
| 日志 | tracing |
|
||
|
||
## License
|
||
|
||
MIT
|