项目结构

概述

良好的项目结构对于构建可维护和可扩展的应用程序至关重要。本章节将介绍Silent框架推荐的项目结构和最佳实践。

基本项目结构

目录结构

推荐的目录结构如下:

my-silent-app/
├── Cargo.toml
├── src/
│   ├── main.rs
│   ├── routes/
│   │   ├── mod.rs
│   │   ├── api.rs
│   │   └── web.rs
│   ├── handlers/
│   │   ├── mod.rs
│   │   └── user.rs
│   ├── models/
│   │   ├── mod.rs
│   │   └── user.rs
│   ├── middleware/
│   │   ├── mod.rs
│   │   └── auth.rs
│   ├── config/
│   │   ├── mod.rs
│   │   └── app.rs
│   └── utils/
│       ├── mod.rs
│       └── helpers.rs
├── tests/
│   └── integration_tests.rs
├── static/
│   ├── css/
│   ├── js/
│   └── images/
└── templates/
    └── index.html

模块组织

路由模块

// src/routes/mod.rs
mod api;
mod web;

pub use api::*;
pub use web::*;

pub fn configure() -> Route {
    Route::new("")
        .hook(ExceptionHandler::new())
        .nest("/api", api::routes())
        .nest("/", web::routes())
}

处理器模块

// src/handlers/user.rs
use silent::prelude::*;
use crate::models::User;

pub async fn get_user(req: Request) -> Result {
    let user_id = req.param("id")?;
    let user = User::find(user_id).await?;
    Ok(Json(user))
}

中间件模块

// src/middleware/auth.rs
use silent::prelude::*;

pub struct AuthMiddleware;

#[async_trait]
impl Handler for AuthMiddleware {
    async fn handle(&self, req: Request, next: Next<'_>) -> Result {
        // 身份验证逻辑
        if let Some(token) = req.header("Authorization") {
            // 验证token
            next.run(req).await
        } else {
            Err(SilentError::Unauthorized("Missing token".to_string()))
        }
    }
}

配置管理

应用配置

// src/config/app.rs
use serde::Deserialize;

#[derive(Deserialize)]
pub struct AppConfig {
    pub server_port: u16,
    pub database_url: String,
    pub redis_url: Option<String>,
}

impl AppConfig {
    pub fn from_env() -> Self {
        // 从环境变量加载配置
        todo!()
    }
}

测试组织

集成测试

// tests/integration_tests.rs
use silent::prelude::*;
use my_silent_app;

#[tokio::test]
async fn test_get_user() {
    let app = my_silent_app::create_app();
    let response = app
        .oneshot(
            Request::builder()
                .uri("/api/users/1")
                .method("GET")
                .build(),
        )
        .await
        .unwrap();

    assert_eq!(response.status(), 200);
}

静态资源

静态文件服务

// src/routes/web.rs
use silent::prelude::*;

pub fn routes() -> Route {
    Route::new("")
        .nest("/static", static_files())
        .get("/", serve_index)
}

fn static_files() -> Route {
    Route::new("")
        .hook(Cache::new().max_age(3600))
        .static_dir("static")
}

最佳实践

  1. 模块化:将相关功能组织在一起

  2. 关注点分离:不同类型的代码放在不同目录

  3. 清晰的依赖关系:避免循环依赖

  4. 统一的错误处理:集中管理错误类型

  5. 配置管理:使用统一的配置管理方式

  6. 测试友好:便于编写和维护测试

示例应用

主程序入口

// src/main.rs
use silent::prelude::*;
mod routes;
mod handlers;
mod models;
mod middleware;
mod config;
mod utils;

#[tokio::main]
async fn main() {
    // 初始化日志
    tracing_subscriber::fmt::init();

    // 加载配置
    let config = config::AppConfig::from_env();

    // 创建应用路由
    let app = routes::configure();

    // 启动服务器
    Server::new()
        .bind(format!("0.0.0.0:{}", config.server_port))
        .run(app)
        .await;
}

通过遵循这些项目结构建议,您可以更好地组织和管理Silent框架应用程序,提高代码的可维护性和可扩展性。良好的项目结构不仅有助于开发效率,还能促进团队协作和代码复用。

Last updated

Was this helpful?