5.6 KiB
5.6 KiB
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. 安装依赖
# 安装 sqlx-cli (可选,用于数据库迁移管理)
cargo install sqlx-cli --no-default-features --features sqlite
3. 配置环境变量
cp .env.example .env
编辑 .env 文件:
DATABASE_URL=sqlite:./blog.db
JWT_SECRET=你的密钥至少32个字符
BIND_ADDR=127.0.0.1:8080
RUST_LOG=debug
4. 运行
# 开发模式
cargo run
# 生产构建
cargo build --release
strip target/release/blog_backend # 可选:减小体积
./target/release/blog_backend
API 接口
认证
| 方法 | 路径 | 说明 | 认证 |
|---|---|---|---|
| POST | /api/auth/register |
用户注册 | 否 |
| POST | /api/auth/login |
用户登录 | 否 |
注册/登录请求:
{
"email": "user@example.com",
"password": "password123"
}
响应:
{
"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
创建文章请求:
{
"title": "文章标题",
"content": "文章内容",
"published": true
}
分页响应:
{
"data": [...],
"page": 1,
"limit": 10,
"total": 100,
"total_pages": 10
}
文件上传
| 方法 | 路径 | 说明 | 认证 |
|---|---|---|---|
| POST | /api/upload |
上传图片 | 是 |
请求: multipart/form-data,字段名 file
限制:
- 支持格式:jpg, jpeg, png, webp
- 最大大小:5MB
- 包含 Magic Number 校验防止伪装文件
响应:
{
"filename": "uuid.jpg",
"url": "/uploads/uuid.jpg"
}
静态文件
| 路径 | 说明 |
|---|---|
/uploads/* |
访问上传的文件 |
认证说明
需要认证的接口,请在请求头中添加:
Authorization: Bearer <token>
限流规则
| 接口类型 | 限制 |
|---|---|
| 全局 | 60 请求/分钟 |
| 认证接口 | 5 请求/分钟 |
| 上传接口 | 5 请求/分钟 |
部署
1. 构建发布版本
cargo build --release
strip target/release/blog_backend
2. 复制文件到服务器
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. 服务器配置
# 创建目录
mkdir -p /opt/blog/uploads
# 编辑配置
vim /opt/blog/.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:
[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
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable blog
sudo systemctl start blog
sudo systemctl status blog
5. 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 测试。
测试流程:
- 运行 Register 或 Login (自动保存 Token)
- 运行 Create Post (自动保存 Post ID)
- 测试其他接口
技术栈
| 组件 | 技术 |
|---|---|
| Web 框架 | Actix-web 4 |
| 数据库 | SQLite + SQLx |
| 认证 | JWT (jsonwebtoken) |
| 密码哈希 | Argon2 |
| 限流 | actix-governor |
| 日志 | tracing |
License
MIT