2025年最完整Rust全栈开发指南:从0到1构建Web应用

2025年最完整Rust全栈开发指南:从0到1构建Web应用

【免费下载链接】webapp.rs A web application completely written in Rust. 🌍 【免费下载链接】webapp.rs 项目地址: https://gitcode.com/gh_mirrors/we/webapp.rs

你还在为JavaScript全栈开发的复杂性而烦恼吗?想体验用单一语言构建高性能前后端的乐趣?本文将带你从零开始,用Rust打造一个完整的Web应用,涵盖Actix-web后端、Yew前端框架、Diesel ORM和PostgreSQL数据库,让你掌握Rust全栈开发的核心技能。

读完本文你将获得:

  • 搭建Rust全栈开发环境的详细步骤
  • 构建RESTful API服务的最佳实践
  • 使用WebAssembly实现高性能前端交互
  • 数据库设计与ORM集成的实战经验
  • 容器化部署与CI/CD流程配置

项目架构概览

WebApp.rs是一个完全用Rust编写的Web应用,展示了如何将Rust生态系统的各种组件无缝集成,构建现代化Web应用。

mermaid

核心技术栈

组件技术选择作用
后端框架Actix-web异步HTTP服务器,提供高性能API服务
前端框架YewRust编写的现代Web前端框架,编译为WebAssembly
ORMDieselRust ORM工具,处理数据库交互
数据库PostgreSQL关系型数据库,存储应用数据
认证JWT基于令牌的身份验证机制
构建工具CargoRust包管理器和构建系统
WebAssembly工具wasm-pack构建和打包WebAssembly模块
前端打包RollupJavaScript模块打包器

环境搭建

系统要求

  • 操作系统:Linux (Ubuntu/Debian推荐)
  • Rust版本:1.56.0+ (使用rustup安装)
  • 数据库:PostgreSQL 12+
  • 其他工具:wasm-pack、rollup、diesel_cli

依赖安装

# Ubuntu/Debian系统依赖
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev npm wget

# 安装Rust
wget https://sh.rustup.rs -O rustup-init
sudo sh rustup-init -y
source $HOME/.cargo/env

# 安装WebAssembly工具链
cargo install wasm-pack

# 安装前端打包工具
sudo npm install -g rollup

# 安装Diesel ORM工具
cargo install diesel_cli --no-default-features --features "postgres"

项目获取

git clone https://gitcode.com/gh_mirrors/we/webapp.rs
cd webapp.rs

项目结构解析

WebApp.rs采用模块化设计,将前后端分离但使用同一语言开发,项目结构如下:

webapp.rs/
├── Cargo.toml          # 工作区配置
├── Config.toml         # 应用配置
├── backend/            # 后端服务
│   ├── src/
│   │   ├── main.rs     # 后端入口点
│   │   ├── database.rs # 数据库交互
│   │   ├── http/       # HTTP处理逻辑
│   │   └── server/     # 服务器配置
├── frontend/           # 前端应用
│   ├── src/
│   │   ├── lib.rs      # 前端入口点
│   │   ├── component/  # Yew组件
│   │   ├── route.rs    # 前端路由
│   │   └── service/    # 服务与API调用
├── migrations/         # 数据库迁移脚本
└── static/             # 静态资源

核心配置文件解析

Cargo.toml (工作区配置):

[package]
name = "webapp"
version = "1.0.0"
edition = "2018"
description = "A web application completely written in Rust"
keywords = ["web", "app", "webapp", "wasm", "webassembly"]

[workspace]
members = [
    "backend",
    "frontend",
]

[dependencies]
diesel = { version = "1.4.8", optional = true }
serde = { version = "1.0.147", features = ["derive"] }
toml = "0.5.8"

Config.toml (应用配置):

[server]
url = "http://127.0.0.1:30080"
cert = "tls/cert.pem"
key = "tls/key.pem"
redirect-from = [
    "http://127.0.0.1:30081",
    "https://127.0.0.1:30082",
]

[log]
actix-web = "debug"
webapp = "trace"

[postgres]
host = "127.0.0.1"
username = "username"
password = "password"
database = "database"

后端开发

数据库设计与迁移

WebApp.rs使用Diesel ORM与PostgreSQL交互,首先定义数据库模型:

migrations/2018-07-04-055234_create_sessions/up.sql

CREATE TABLE sessions (
    token TEXT PRIMARY KEY
)

数据库交互逻辑封装在database.rs中,使用Actix的Actor模型处理异步数据库操作:

// backend/src/database.rs
use actix::prelude::*;
use diesel::{insert_into, prelude::*, r2d2::Pool};
use webapp::{protocol::model::Session, schema::sessions::dsl::*};

/// 数据库执行器actor
pub struct DatabaseExecutor(pub Pool<ConnectionManager<PgConnection>>);

impl Actor for DatabaseExecutor {
    type Context = SyncContext<Self>;
}

/// 创建会话消息
pub struct CreateSession(pub String);

impl Message for CreateSession {
    type Result = Result<Session>;
}

impl Handler<CreateSession> for DatabaseExecutor {
    type Result = Result<Session>;

    fn handle(&mut self, msg: CreateSession, _: &mut Self::Context) -> Self::Result {
        // 插入会话到数据库
        debug!("Creating new session: {}", msg.0);
        Ok(insert_into(sessions)
            .values(&Session::new(msg.0))
            .get_result::<Session>(&self.0.get()?)?)
    }
}

认证流程实现

认证系统是Web应用的核心组件,WebApp.rs实现了基于会话令牌的认证机制:

backend/src/http/login_credentials.rs

pub async fn login_credentials(
    payload: Json<LoginCredentials>,
    database: Data<Addr<DatabaseExecutor>>,
) -> Result<HttpResponse, Error> {
    let r = payload.into_inner();

    debug!("User {} is trying to login", r.username);
    // 验证用户名和密码(简化版:用户名和密码必须相同)
    if r.username.is_empty() || r.password.is_empty() || r.username != r.password {
        return Err(ErrorUnauthorized("wrong username or password"));
    }

    // 创建新令牌
    match Token::create(&r.username) {
        Ok(token) => {
            // 在数据库中更新会话
            let result = database
                .send(CreateSession(token))
                .await
                .map_err(ErrorInternalServerError)?;
            Ok(HttpResponse::Ok().json(Login(result.map_err(ErrorInternalServerError)?)))
        }
        Err(e) => Err(e.into()),
    }
}

API设计与实现

后端API采用RESTful设计风格,主要端点包括:

  • POST /api/login/credentials - 凭证登录
  • POST /api/login/session - 会话登录
  • POST /api/logout - 登出

请求/响应结构定义在protocol模块中:

src/protocol/request.rs

#[derive(Debug, PartialEq, Deserialize, Serialize)]
/// 基于凭证的登录请求
pub struct LoginCredentials {
    /// 登录用户名
    pub username: String,
    
    /// 登录密码
    pub password: String,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
/// 基于会话的登录请求
pub struct LoginSession(pub Session);

#[derive(Debug, PartialEq, Deserialize, Serialize)]
/// 登出请求
pub struct Logout(pub Session);

前端开发

Yew组件开发

WebApp.rs使用Yew框架构建前端界面,采用组件化设计:

frontend/src/component/login.rs

/// 登录组件数据模型
pub struct LoginComponent {
    component_link: ComponentLink<LoginComponent>,
    cookie_service: CookieService,
    fetch_task: Option<FetchTask>,
    inputs_disabled: bool,
    login_button_disabled: bool,
    password: String,
    router_agent: Box<dyn Bridge<RouteAgent<()>>>,
    uikit_service: UIkitService,
    username: String,
}

impl Component for LoginComponent {
    type Message = Message;
    type Properties = ();

    /// 初始化例程
    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self {
            cookie_service: CookieService::new(),
            fetch_task: None,
            inputs_disabled: false,
            login_button_disabled: true,
            password: String::new(),
            router_agent: RouteAgent::bridge(link.callback(|_| Message::Ignore)),
            component_link: link,
            uikit_service: UIkitService::new(),
            username: String::new(),
        }
    }
    
    // 视图渲染
    fn view(&self) -> Html {
        let onclick = self.component_link.callback(|_| Message::LoginRequest);
        let oninput_username = self
            .component_link
            .callback(|e: InputData| Message::UpdateUsername(e.value));
        let oninput_password = self
            .component_link
            .callback(|e: InputData| Message::UpdatePassword(e.value));
        html! {
            <div class="uk-card uk-card-default uk-card-body uk-width-1-3@s uk-position-center",>
                <h1 class="uk-card-title",>{TEXT_LOGIN}</h1>
                <form>
                    <fieldset class="uk-fieldset",>
                        <input class="uk-input uk-margin",
                            placeholder=INPUT_USERNAME,
                            disabled=self.inputs_disabled,
                            value=&self.username,
                            oninput=oninput_username />
                        <input class="uk-input uk-margin-bottom",
                            type="password",
                            placeholder=INPUT_PASSWORD,
                            disabled=self.inputs_disabled,
                            value=&self.password,
                            oninput=oninput_password />
                        <button class="uk-button uk-button-primary",
                            type="submit",
                            disabled=self.login_button_disabled,
                            onclick=onclick>{TEXT_LOGIN}</button>
                    </fieldset>
                </form>
            </div>
        }
    }
}

状态管理与路由

前端路由使用yew-router实现,主要路由包括:

  • /login - 登录页面
  • /content - 内容页面(需要认证)

frontend/src/route.rs

#[derive(Switch, Debug, Clone)]
pub enum RouterTarget {
    #[to = "/content"]
    Content,
    #[to = "/login"]
    Login,
    #[to = "/"]
    LoginRedirect,
}

会话管理通过Cookie和定时任务实现,确保用户认证状态:

// 在Content组件创建时验证会话
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
    // 验证认证状态
    let mut router_agent = RouteAgent::bridge(link.callback(|_| Message::Ignore));
    let cookie_service = CookieService::new();
    let mut session_timer_agent = SessionTimerAgent::bridge(link.callback(|_| Message::Ignore));
    if cookie_service.get(SESSION_COOKIE).is_err() {
        info!("未找到会话令牌,重定向到登录页面");
        router_agent.send(ChangeRoute(RouterTarget::Login.into()));
    } else {
        // 启动会话保持定时器
        session_timer_agent.send(session_timer::Request::Start);
    }
    
    // 返回组件实例
    Self { /* 组件状态初始化 */ }
}

构建与部署

构建流程

WebApp.rs使用Makefile自动化构建流程,主要目标包括:

# 构建后端
build-backend:
	cargo build $(BACKEND_ARGS)

# 构建前端
build-frontend:
	cd frontend && \
		wasm-pack build --target web $(FRONTEND_ARGS) && \
		rollup ./main.js --format iife --file ./pkg/webapp_frontend.js

# 完整构建
all: build-backend build-frontend

执行构建命令:

# 开发构建
make all

# 发布构建
make all GENERAL_ARGS=--release

本地开发环境

# 启动后端服务
make run-backend

# 启动前端开发服务器
make run-frontend

# 启动PostgreSQL数据库
make run-postgres

应用配置通过Config.toml文件管理,可以根据需要修改服务器地址、数据库连接等参数:

[server]
url = "http://127.0.0.1:30080"
cert = "tls/cert.pem"
key = "tls/key.pem"

[postgres]
host = "127.0.0.1"
username = "username"
password = "password"
database = "database"

容器化部署

WebApp.rs提供容器化部署方案,使用Podman或Docker:

# 构建容器镜像
make deploy

# 启动应用和数据库容器
sudo make run-app

部署架构如下:

mermaid

实战开发:功能扩展

添加用户注册功能

  1. 数据库迁移:创建用户表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    email TEXT UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
  1. 后端实现:添加注册API
// src/http/register.rs
pub async fn register(
    payload: Json<RegisterRequest>,
    database: Data<Addr<DatabaseExecutor>>,
) -> Result<HttpResponse, Error> {
    // 密码哈希
    let password_hash = bcrypt::hash(&payload.password, 10)
        .map_err(ErrorInternalServerError)?;
    
    // 创建用户
    let result = database
        .send(CreateUser {
            username: payload.username.clone(),
            email: payload.email.clone(),
            password_hash,
        })
        .await
        .map_err(ErrorInternalServerError)?;
    
    Ok(HttpResponse::Ok().json(result.map_err(ErrorInternalServerError)?))
}
  1. 前端实现:添加注册组件
// src/component/register.rs
struct RegisterComponent {
    // 组件状态...
}

impl Component for RegisterComponent {
    // 实现注册表单和API调用...
}

常见问题与解决方案

CORS问题

问题:前端开发时跨域请求被阻止
解决方案:在Actix-web中配置CORS中间件

use actix_cors::Cors;

// 在服务器配置中添加
let cors = Cors::default()
    .allow_any_origin()
    .allow_any_method()
    .allow_any_header();

App::new()
    .wrap(cors)
    // 其他配置...

数据库连接池

问题:高并发下数据库连接耗尽
解决方案:配置合理的连接池大小

// 配置数据库连接池
let manager = ConnectionManager::<PgConnection>::new(database_url);
let pool = Pool::builder()
    .max_size(10) // 设置最大连接数
    .build(manager)
    .expect("Failed to create pool");

Wasm打包体积优化

问题:前端Wasm文件体积过大
解决方案:启用Rust编译器优化和wasm-pack压缩

# 优化构建命令
wasm-pack build --target web --release -- --features=wee_alloc
rollup ./main.js --format iife --file ./pkg/webapp_frontend.js --silent

总结与展望

通过本文,你已经掌握了使用Rust构建全栈Web应用的核心技术,包括:

  • 使用Actix-web构建高性能后端服务
  • 基于Yew和WebAssembly开发交互前端
  • Diesel ORM与PostgreSQL数据库集成
  • 用户认证与会话管理实现
  • 项目构建与容器化部署

进阶学习路线

  1. 性能优化

    • 实现数据库查询缓存
    • 前端渲染性能调优
    • HTTP/2支持配置
  2. 功能扩展

    • 添加JWT认证
    • 实现WebSocket实时通信
    • 集成全文搜索引擎
  3. 工程化

    • 完善测试覆盖
    • CI/CD流程配置
    • 监控与日志系统

Rust全栈开发正处于快速发展阶段,随着WebAssembly生态的成熟,Rust有望成为前端开发的重要选择。立即动手尝试本文介绍的技术,开启你的Rust全栈开发之旅吧!

如果你觉得本文对你有帮助,请点赞、收藏并关注,下期我们将深入探讨Rust Web应用的性能优化和测试策略。


附录:完整技术栈版本信息

组件版本说明

【免费下载链接】webapp.rs A web application completely written in Rust. 🌍 【免费下载链接】webapp.rs 项目地址: https://gitcode.com/gh_mirrors/we/webapp.rs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值