actix-cloudActix Cloud is an all-in-one web framework bas... | actix-cloudActix Cloud is an all-in-one web framework bas...
actix-cloud
Actix Cloud is an all-in-one web framework based on Actix Web.

Features
Actix Cloud is highly configurable. You can only enable needed features, implement your own feature backend or even use other libraries.

logger (Default: Enable)
i18n (Default: Disable)
security (Embedded)
memorydb backend
default (Embedded)
redis (Default: Disable)
auth (Embedded)
session (Default: Disable)
Guide
Quick Start
You can refer to Hello world example for basic usage.

Application
Since application configuration can be quite dynamic, you need to build on your own. Here are some useful middlewares:

App::new()
.wrap(middleware::Compress::default()) // compress page
.wrap(SecurityHeader::default().build()) // default security header
.wrap(SessionMiddleware::builder(memorydb.clone(), Key::generate()).build()) // session
...
.app_data(state_cloned.clone())
logger
We use tracing as our logger library. It is thread safe. You can use it everywhere.

Start logger:

LoggerBuilder::new().level(Level::DEBUG).start() // colorful output
LoggerBuilder::new().json().start() // json output
You can also customize the logger with filter, transformer, etc.

Reinit logger (e.g., in plugins), or manually send logs:

logger.init(LoggerBuilder::new());
logger.sender().send(...);
i18n
We use rust-i18n-support from rust-i18n as our i18n core.

Load locale:

let mut locale = Locale::new(String::from("en-US"));
locale.add_locale(i18n!("locale"));
Translate:

t!(locale, "hello.world")
t!(locale, "hello.name", name = "MEME")
See examples for more usage.

security
Middleware to add security headers:

app.wrap(SecurityHeader::default().build())
Default header:

X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Cross-Origin-Opener-Policy: same-origin
Content-Security-Policy: default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'
Enable HSTS when using HTTPS:

security_header.set_default_hsts();
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
memorydb-default
Actix Cloud has a default memory database backend used for sessions. You can also use your own backend if you implement actix_cloud::memorydb::MemoryDB.

Note: the default backend does not have memory limitation, DDoS is possible if gateway rate limiting is not implemented

DefaultBackend::new().await.unwrap()
memorydb-redis
Redis can be used as another backend for memory database.

RedisBackend::new("redis://user:[email protected]:6379/0").await.unwrap(),
auth
Authentication is quite simple, you only need to implement an extractor and a checker.

Extractor is used to extract your own authentication type from request. For example, assume we use 0 for guest and 1 for admin. Our authentication type is just Vec<u32>:

fn perm_extractor(req: &mut ServiceRequest) -> Vec<u32> {
let mut ret = Vec::new();
ret.push(0); // guest permission is assigned by default.

// test if query string has admin=1.
let qs = QString::from(req.query_string());
if qs.get("admin").is_some_and(|x| x == "1") {
ret.push(1);
}
ret
}
Checker is used to check the permission, the server will return 403 if the return value is false:

fn is_guest(p: Vec<u32>) -> bool {
p.into_iter().find(|x| *x == 0).is_some()
}
Then build the Router and configure in the App using build_router:

app.service(scope("/api").configure(build_router(...)))
session
Most features and usages are based on actix-session. Except for these:

MemoryDB is the only supported storage.
Error uses actix-cloud::error::Error.
You can set _ttl in the session to override the TTL of the session.
app.wrap(SessionMiddleware::builder(memorydb.clone(), Key::generate()).build())
License
This project is licensed under the MIT license.
https://crates.io/crates/actix-cloud crates.io: Rust Package Registry