Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Spring and Spring Boot Migration
Spring 与 Spring Boot 迁移

What you’ll learn: How Spring and Spring Boot concepts translate into idiomatic Rust service architecture, which Rust libraries usually replace familiar Spring features, and how to migrate one service without trying to clone the whole Spring ecosystem.
本章将学习: Spring 与 Spring Boot 的核心概念如何迁移到符合 Rust 习惯的服务架构中,哪些 Rust 库通常会替代熟悉的 Spring 功能,以及怎样迁移一个服务而不是妄图克隆整个 Spring 生态。

Difficulty: 🟡 Intermediate
难度: 🟡 中级

The biggest Spring-to-Rust mistake is searching for “the Rust Spring Boot.”
从 Spring 迁到 Rust 时,最大的误区就是拼命去找“Rust 版 Spring Boot”。

Rust web development is more toolkit-oriented and much less centered around one giant framework.
Rust 的 Web 开发生态更偏工具箱式组合,而不是围绕一个超级框架打天下。

Concept Mapping
概念映射

Spring concept
Spring 概念
Common Rust direction
Rust 常见对应方向
@RestControlleraxum or actix-web handlers
axumactix-web 的 handler
dependency injection containerexplicit construction plus shared state
显式构造加共享状态
@ConfigurationPropertiesconfig structs plus env/file loading
配置结构体加环境变量或文件加载
servlet filter chaintower middleware
tower 中间件
@ControllerAdviceIntoResponse or top-level error mapping
IntoResponse 或顶层错误映射
JpaRepositorysqlx, sea-orm, or handwritten repositories
sqlxsea-orm 或手写 repository

What Changes the Most
变化最大的地方

1. Dependency Wiring Becomes Explicit
依赖装配会变得显式

#![allow(unused)]
fn main() {
#[derive(Clone)]
struct AppState {
    user_service: UserService,
    audit_service: AuditService,
}
}

Spring relies on the container to build the object graph.
Spring 依赖容器去构建对象图。

Rust usually wants that wiring visible in startup code.
Rust 更希望这套装配逻辑直接写在启动代码里,让人一眼看明白。

2. Reflection Stops Being the Center
反射不再处在系统中心

Spring leans heavily on annotations, proxies, and runtime discovery.
Spring 很依赖注解、代理和运行时发现机制。

Rust ecosystems usually prefer:
Rust 生态通常更偏好:

  • derives for data boilerplate
    用 derive 处理数据样板代码。
  • middleware for cross-cutting concerns
    用中间件承接横切关注点。
  • plain functions plus explicit types
    用普通函数和显式类型完成主逻辑。

3. Data Access Gets More Honest
数据访问会变得更诚实

Spring Boot teams often carry JPA habits such as inferred repositories and hidden query behavior.
Spring Boot 团队往往会带着 JPA 的思维惯性,比如推断式 repository 和隐藏的查询行为。

Rust teams usually choose earlier between explicit SQL, a lighter ORM, or a small handwritten repository layer.
Rust 团队通常会更早在显式 SQL、较轻的 ORM、或小型手写 repository 层之间做选择。

For migration work, sqlx is often the easiest mental reset.
在迁移场景里,sqlx 往往是最容易把脑子掰正过来的选择。

Typical Service Shape
典型服务形态

Spring Boot often looks like this:
Spring Boot 常见结构是这样:

controller -> service -> repository -> database

Rust often looks like this:
Rust 服务更常见的是这样:

router -> handler -> service -> repository -> database

The key change is not the number of layers; it is the disappearance of hidden framework behavior.
真正的关键变化不在于层数,而在于隐藏的框架行为被拿掉了。

From Controller to Handler
从 Controller 到 Handler

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public UserResponse getUser(@PathVariable UUID id) {
        return userService.getUser(id);
    }
}
#![allow(unused)]
fn main() {
async fn get_user(
    State(state): State<AppState>,
    Path(id): Path<Uuid>,
) -> Result<Json<UserResponse>, AppError> {
    let user = state.user_service.get_user(id).await?;
    Ok(Json(user))
}
}

The handler is just a function, which is a huge part of why Rust services feel easier to trace.
handler 就是一个普通函数,这也是 Rust 服务为什么会显得更容易追踪的一大原因。

Practical Advice
实用建议

  • keep the HTTP contract stable first
    先把 HTTP 契约稳住。
  • migrate one bounded context at a time
    一次迁一个边界清晰的上下文。
  • move business rules before chasing framework parity
    先搬业务规则,再谈框架表面对齐。
  • do not rebuild Spring in macros
    别想着用宏把 Spring 整个再造一遍。

Rust migration works best when the result is a good Rust service, not a bitter imitation of a Spring service.
迁移最成功的状态,是最后得到一个好的 Rust 服务,而不是一个带着怨气模仿 Spring 的 Rust 程序。