Project-Directory-Structure[20261003233749]

0 阅读1分钟

项目目录结构

项目代码:github.com/hyperlane-d…

在使用 hyperlane 构建生产级 Web 应用时,有效地组织代码库与编写优质代码同样重要。一个结构良好的项目目录使你的代码库更易于导航、测试和维护。本文将探讨 hyperlane 项目的推荐目录结构,并解释每个层的用途。

概览

Hyperlane 遵循分层架构模式,将关注点分离到不同的目录中。推荐的结构如下:

├── application/controller/domain/exception/mapper/middleware/model/repository/service/utils/view
├── bootstrap/application/framework
├── config/application/framework
├── plugin/database/env/logger/mysql/postgresql/process/redis
├── resources/docker/env/sql/static/templates

该结构受领域驱动设计(DDD)原则启发,适用于任何规模的项目 —— 从小型的 API 到大型企业级应用。

应用层

application 目录是你项目的核心。它包含所有业务逻辑,组织在以下几个子目录中:

Controller(控制器)

controller 目录包含你的路由处理程序 —— HTTP 请求的入口点。每个控制器对应一个特定的资源或领域概念。控制器负责接收请求、提取参数、调用适当的服务并返回响应。

在 hyperlane 中,控制器通常使用 #[route] 属性实现为结构体:

#[route("/test/{text}")]
struct Route;

控制器应该保持精简 —— 它们不应包含业务逻辑。相反,它们应将工作委托给服务层。

Domain(领域)

domain 目录保存你的核心业务实体、值对象和领域服务。这些是应用程序的基本构建块,代表你正在建模的业务概念。

Model(模型)

model 目录包含数据传输对象(DTO)、请求/响应模型,以及任何表示流经应用程序的数据形状的数据结构。这些模型用于反序列化请求体和序列化响应数据。

let json_body: T = ctx.get_request().get_body_json::<T>();

Service(服务)

service 目录是你的大部分业务逻辑所在之处。服务编排操作、执行业务规则,并协调应用程序不同部分之间的交互。它们充当控制器层和仓库层之间的桥梁。

Repository(仓库)

repository 目录包含数据访问逻辑 —— 与数据库、缓存或外部 API 交互的代码。仓库抽象了数据存储和检索的细节,为服务层提供干净的接口。

Middleware(中间件)

middleware 目录存放自定义中间件组件。在 hyperlane 中,中间件使用 ServerHook 特性实现:

struct RequestMiddleware;
impl ServerHook for RequestMiddleware {
    async fn new(stream: &mut Stream, _: &mut Context) -> Self { Self }
    async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
        ctx.get_mut_response().set_version(HttpVersion::Http1_1).set_status_code(200);
        Status::Continue
    }
}
server.request_middleware::<RequestMiddleware>();

常见的中间件用例包括身份验证、日志记录、CORS 处理和请求验证。

Exception 和 Mapper

exception 目录包含自定义错误类型和错误处理逻辑。mapper 目录包含在不同数据表示之间转换的函数 —— 例如,将数据库行映射到领域模型。

Utils(工具)

utils 目录用于不属于任何其他类别的共享工具函数和辅助函数。这可能包括字符串操作、日期格式化或加密辅助函数。

View(视图)

view 目录包含模板文件和与视图相关的逻辑,用于渲染 HTML 或其他格式化输出的应用程序。

引导层

bootstrap 目录包含应用程序初始化和启动代码。这是你配置和启动 hyperlane 服务器的地方:

#[tokio::main]
async fn main() {
    let mut server: Server = Server::default();
    let server_control_hook: ServerControlHook = server.run().await.unwrap_or_default();
    server_control_hook.wait().await;
}

bootstrap/application 子目录包含应用程序特定的初始化逻辑,而 bootstrap/framework 包含框架级别的配置。

配置层

config 目录存储所有配置文件和配置加载逻辑。Hyperlane 支持基于 JSON 的配置:

let config_json = r#"{ "address": "0.0.0.0:80", "nodelay": true, "ttl": 64 }"#;
let mut server = Server::default();
server.config_from_json(config_json);

config/application 子目录保存应用程序级别的设置,而 config/framework 保存框架级别的设置,如服务器超时和缓冲区大小。

插件层

plugin 目录包含与外部系统和服务的集成:

  • database/ — 数据库连接池和查询构建器
  • mysql/ — MySQL 特定的数据库驱动程序和配置
  • postgresql/ — PostgreSQL 特定的数据库驱动程序和配置
  • redis/ — Redis 缓存集成
  • logger/ — 日志框架配置
  • env/ — 环境变量管理
  • process/ — 进程管理工具

资源层

resources 目录包含非代码资产:

  • docker/ — Docker 配置文件和 Dockerfile
  • env/ — 环境配置文件
  • sql/ — SQL 迁移文件和种子数据
  • static/ — 静态资源,如 CSS、JavaScript 和图片
  • templates/ — HTML 或文本模板

请求配置

Hyperlane 的 RequestConfig 允许你微调服务器如何处理传入的请求:

let request_config_json = r#"{ "buffer_size": 8192, "max_path_size": 8192, "max_header_count": 100, "max_header_key_size": 8192, "max_header_value_size": 8192, "max_body_size": 2097152, "read_timeout_ms": 6000 }"#;
let request_config = RequestConfig::from_json(request_config_json).unwrap();

这些设置应在 config 层中配置,并在创建服务器时应用。

服务器配置

同样,ServerConfig 控制服务器级别的行为:

let mut config: ServerConfig = ServerConfig::default();
config.set_address("0.0.0.0:80");
config.set_nodelay(Some(true));
config.set_ttl(Some(128));

将所有内容整合在一起

一个典型的 hyperlane 应用程序入口点将所有这些层联系在一起:

#[hyperlane(server: Server)]
#[hyperlane(server_config: ServerConfig)]
#[tokio::main]
async fn main() {
    // 加载配置
    server.server_config(server_config);

    // 注册路由
    server.route::<Route>("/test");

    // 注册中间件
    server.request_middleware::<RequestMiddleware>();
    server.response_middleware::<ResponseMiddleware>();

    // 启动服务器
    let server_control_hook = server.run().await.unwrap_or_default();
    server_control_hook.wait().await;
}

最佳实践

  1. 保持控制器精简 —— 业务逻辑属于服务层,而非控制器。
  2. 使用仓库模式 —— 通过仓库接口抽象数据访问,以便于测试。
  3. 将配置与代码分离 —— 对特定于环境的设置使用 JSON 配置文件。
  4. 利用中间件 —— 身份验证和日志记录等横切关注点应作为中间件实现。
  5. 遵循单一职责原则 —— 每个模块应有一个明确的用途。
  6. 使用属性宏 —— 通过 hyperlane 强大的属性宏系统减少样板代码。

总结

Hyperlane 项目的推荐目录结构促进了清晰的关注点分离,使你的代码库更易于理解、测试和维护。通过将代码组织到应用层、引导层、配置层、插件层和资源层中,你创建了一个可以随项目需求扩展的坚实基础。随着你对 hyperlane 的熟悉程度加深,你可以调整此结构以满足你的特定需求,同时保持清洁架构的核心原则。


项目代码:github.com/hyperlane-d…