项目导读
作为 Java 开发者,你一定熟悉 Spring Boot 的“约定大于配置”,但也忍受过启动时漫长的 Bean 扫描,以及空载时 300MB 起步的内存占用。
作为 Python 开发者,你享受 FastAPI 的开发速度,但当 QPS 上来时,你不得不面对 GIL 锁带来的吞吐量瓶颈,甚至要把业务逻辑迁移到 Go。Rust 的 Web 生态已经成熟。特别是 Axum(基于 Tokio)和 Sqlx(异步数据库驱动)的组合,被称为现代后端开发的“黄金搭档”。
在这个实战项目中,我们将构建一个短链接服务(URL Shortener)。这不仅仅是一个 Demo,它包含了商业项目必备的要素:数据库连接池、依赖注入(状态管理)、统一错误处理、结构化日志以及 Docker 极小镜像构建。
准备好见证奇迹了吗?我们将把一个完整的 Web 服务打包进 20MB 的 Docker 镜像中,且运行时内存仅需 15MB。
🎯 本项目学习目标
- 框架选型:掌握 Axum 框架的核心概念(路由、提取器、中间件)。
- 数据持久化:使用 Sqlx 操作 PostgreSQL,体验编译期 SQL 检查的黑科技。
- 架构设计:学习如何在 Rust 中实现类似 Spring 的“依赖注入”(通过
AppState)。 - 错误处理:构建全局统一的错误处理机制(
IntoResponse),告别混乱的try-catch。 - 云原生交付:编写多阶段构建的
Dockerfile,产出 Distroless 级别的超小镜像。 - AI 辅助:利用 AI 生成 SQL 迁移脚本和集成测试代码。
B.1 项目初始化与架构规划
不同于 Python 的随意文件结构,Rust 商业项目讲究模块化。
B.1.1 创建项目与依赖
1cargo new short_link_service 2cd short_link_service 3
编辑 Cargo.toml,我们要引入“全家桶”:
1[package] 2name = "short_link_service" 3version = "0.1.0" 4edition = "2021" 5 6[dependencies] 7# Web 框架,Tokio 官方出品,人体工程学极佳 8axum = "0.7" 9# 异步运行时 10tokio = { version = "1.0", features = ["full"] } 11# 序列化 12serde = { version = "1.0", features = ["derive"] } 13serde_json = "1.0" 14# 数据库 ORM/Mapper 15sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono"] } 16# 环境变量管理 17dotenvy = "0.15" 18# 结构化日志与追踪 19tracing = "0.1" 20tracing-subscriber = { version = "0.3", features = ["env-filter"] } 21# 唯一 ID 生成 22nanoid = "0.4.0" 23# 错误处理 24thiserror = "1.0" 25
B.1.2 目录结构设计
我们采用经典的分层架构,但比 Java 更轻量:
1src/ 2├── main.rs # 程序入口,组装路由和状态 3├── config.rs # 配置加载 4├── db.rs # 数据库连接池初始化 5├── handlers.rs # 控制器(Controller)逻辑 6├── models.rs # 数据模型(DTO/POJO) 7└── errors.rs # 全局错误定义 8
B.2 数据库先行:Sqlx 的魔法
Java 的 Hibernate/MyBatis 需要 xml 配置或大量的注解,且 SQL 写错了要等到运行时才知道。Sqlx 颠覆了这一点:它在编译时连接数据库检查 SQL 语法。
B.2.1 启动 PostgreSQL
为了方便,我们使用 Docker 启动数据库。
1docker run --name pg -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:15-alpine 2
在项目根目录创建 .env 文件:
1DATABASE_URL=postgres://postgres:password@localhost:5432/postgres 2RUST_LOG=debug 3
B.2.2 AI 辅助生成 Schema
我们需要一张表存短链接。
Prompt 建议:
“我正在用 Rust 和 Postgres 做短链接系统。请帮我写一个
CREATE TABLE的 SQL 语句。字段包括:id (char 6, 主键), original_url (text, 非空), created_at (timestamp), visits (int)。请考虑性能索引。”
AI 会给出 SQL。我们需要安装 sqlx-cli 来管理迁移:
1cargo install sqlx-cli 2sqlx database create 3sqlx migrate add init_schema 4
将 AI 生成的 SQL 填入 migrations/xxxx_init_schema.up.sql:
1CREATE TABLE IF NOT EXISTS links ( 2 id CHAR(6) PRIMARY KEY, 3 original_url TEXT NOT NULL, 4 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), 5 visits INT NOT NULL DEFAULT 0 6); 7
执行迁移:sqlx migrate run。
B.3 核心代码实现
B.3.1 定义数据模型 (src/models.rs)
1use serde::{ 2 3 Deserialize, Serialize}; 4use sqlx::FromRow; 5 6// 对应数据库表结构 7#[derive(Debug, FromRow, Serialize)] 8pub struct Link { 9 10 11 pub id: String, 12 pub original_url: String, 13 pub created_at: chrono::DateTime<chrono::Utc>, 14 pub visits: i32, 15} 16 17// 接收前端创建请求的 DTO 18#[derive(Debug, Deserialize)] 19pub struct CreateLinkReq { 20 21 22 pub url: String, 23} 24 25// 返回给前端的 DTO 26