Skip to content

Modular web framework for building scalable and performant Rust applications

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

Styren/contraband

Repository files navigation

Contraband

Build Status crates.io Documentation License

Contraband is a web framework built on top of actix for creating modular applications in Rust with dependency injection and performant higher-level abstractions.

Contraband is heavily inspired by Spring Boot and Nestjs.

For more information you can check out the examples.

First steps

Create an empty project with Cargo

$ cargo new example-project
$ cd example-project

Add contraband and actix_web to the list of dependencies in Cargo.toml

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

Controllers

Controllers are responsible for handling incoming request and is able to serve multiple routes and HTTP-method types.

In order to create a controller we use structs and attributes. Attributes are used to generate the boilerplate necessary to register all routes and inject all dependencies into the controller.

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!")
    }
}

Note the derive clause. In order to be injected into the Contraband app it needs to derive Injectable. Since Contraband spawns multiple instances it also needs to derive Clone.

Providers

One of the biggest perks of Contraband is the ability to inject arbitrary dependencies into, for example, our controllers. This is done through deriving the aforementioned Injectable-trait.

Below is and example of how an injectable struct can be used for user management.

#[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
    }
}

In order to utilize our new service we can inject it into our HelloController by defining an Arc-pointer to our service.

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

We are now able to use our new service in any methods in HelloController. Below we use our new service for fetching users in a new route.

#[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)
    }
    // ...
}

However in order for the dependency to be resolved when initializing the Contraband runtime we need to register it as a provider. More on that in the next chapter.

Modules

A module is a struct that derives the module-trait and is used to organize our controllers and dependencies into nested building blocks.

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
}

Note how we registered our UserService as a provider. This is required in order to inject the dependency in this scope and enabling its use in our controller.

License

Contraband is licensed under either MIT licensed or Apache 2.0 licensed.

About

Modular web framework for building scalable and performant Rust applications

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages