#web-framework #web #framework #async #http

contraband

Contraband是一个用于构建模块化和可扩展应用程序的Web框架

3个版本

0.1.2 2020年9月28日
0.1.1 2020年9月27日
0.1.0 2020年9月27日

#710 in HTTP服务器


用于contraband_diesel

MIT/Apache

28KB
589

Contraband

Contraband是一个基于actix构建的Web框架,用于在Rust中创建具有依赖注入和高效高级抽象的模块化应用程序。

Contraband深受Spring Boot和Nestjs的启发。

有关更多信息,您可以查看示例

第一步

使用Cargo创建一个空项目

$ cargo new example-project
$ cd example-project

将contraband和actix_web添加到Cargo.toml中的依赖列表

[dependencies]
actix-web = "3"
contraband = "^0.1.0"

控制器

控制器负责处理传入请求,能够服务多个路由和HTTP方法类型。

为了创建一个控制器,我们使用结构体属性。属性用于生成注册所有路由和将所有依赖注入控制器的样板代码。

use contraband::{Injectable, controller};
use contraband::core::ContrabandApp;
use actix_web::HttpResponse;

#[derive(Clone, Injectable)]
struct HelloController;

#[controller]
impl HelloController {
    #[get]
    async fn hello_world(self) -> HttpResponse {
        HttpResponse::Ok().body("Hello world!")
    }
}

注意 derive 子句。为了能够注入Contraband应用程序,它需要 derive Injectable。由于Contraband创建了多个实例,它还需要 derive Clone

提供者

Contraband最大的优点之一是能够通过衍生上述Injectable-trait将任意依赖项注入,例如我们的控制器。

下面是一个如何使用可注入的结构体进行用户管理的示例。

#[derive(Clone, Injectable)]
pub struct UserService;

impl UserService {
    pub async fn add_user(&self, name: &str) {
        // stub
    }

    pub async fn get_user(&self, id: u32) {
        // stub
    }
}

为了利用我们新的服务,我们可以通过定义指向我们的服务的Arc-指针来将其注入到我们的HelloController中。

// ...
#[derive(Clone, Injectable)]
struct HelloController {
    user_service: std::sync::Arc<UserService>
}
// ...

现在我们可以在HelloController中的任何方法中使用我们新的服务。以下我们使用我们的新服务来获取新路由中的用户。

#[controller]
impl HelloController {
    // ...
    #[get("/users/:id")]
    async fn get_users(self, id: actix_web::web::Path<i32>) -> HttpResponse {
        let name = self.user_service.get_user(id);
        HttpResponse::Ok().body(name)
    }
    // ...
}

然而,为了在初始化Contraband运行时解析依赖项,我们需要将其注册为提供者。有关更多信息,请参阅下一章。

模块

模块是一个衍生了module-trait的结构体,用于将我们的控制器和依赖项组织成嵌套构建块。

use contraband::core::ContrabandApp;
use contraband::module;

#[module]
#[controller(HelloController)]
#[provider(UserService)]
struct AppModule;

#[contraband::main]
async fn main() -> std::io::Result<()> {
    ContrabandApp::new()
        .start::<AppModule>()
        .await
}

注意我们如何将UserService注册为提供者。这是在当前作用域中注入依赖项并允许其在控制器中使用所必需的。

许可证

Contraband在MIT许可证Apache 2.0许可证下授权。

依赖项

~36MB
~820K SLoC