https://github.com/harrisdeperceptron/rext-rust-web-framework
Rext is an opinionated framework design to follow best practices for designing and writing backend business logic in Rust
https://github.com/harrisdeperceptron/rext-rust-web-framework
axum framework rust rust-lang
Last synced: about 1 year ago
JSON representation
Rext is an opinionated framework design to follow best practices for designing and writing backend business logic in Rust
- Host: GitHub
- URL: https://github.com/harrisdeperceptron/rext-rust-web-framework
- Owner: HarrisDePerceptron
- Created: 2023-09-12T22:02:45.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-11-09T20:27:03.000Z (over 2 years ago)
- Last Synced: 2025-03-21T03:13:37.294Z (about 1 year ago)
- Topics: axum, framework, rust, rust-lang
- Language: Rust
- Homepage:
- Size: 129 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Rext: Rust Axum Web Framework
Rext is an opinionated framework design to follow best practices for designing and writing backend business logic in Rust :crab:
### Features
- File structure and organization
- Tokio as the async provider
- Axum as the api web framework
- Ready to use WebSockets
- Websockets design to work with rooms (join, leave, message)
- Mongo data access layer included
- Redis Adapter for working with redis async commands
- Stateful horizontal scaling of Websockets
### Getting Started
Fire away 🚀
```
$ cargo run
```
### Writing Apis
**Model**
```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
email: String,
password: String,
}
impl User {
// model methods
}
```
**Data Access layer**
`app/user/user_dao.rs`
```
pub struct UserDao {
fac: Arc,
collection_name: String,
}
impl DaoObj for UserDao {
fn get_factory(&self) -> Arc {
self.fac.clone()
}
fn get_collection_name(&self) -> &str {
&self.collection_name
}
}
```
**Service**
`app/user/user_service.rs`
```
pub struct UserService {
dao: Arc,
}
impl Service for UserService {
fn get_dao(&self) -> Arc> {
self.dao.clone()
}
}
impl UserService {
// extending service methods
}
```
**Routes**
`app/user/user_routes.rs`
```
pub fn user_routes() -> Router> {
Router::new()
.route("/", post(user_create))
.route("/", get(list_user))
.route("/:user_id", get(get_user))
.route("/users/login", post(user_login))
}
```
**Registering Routes**
`server.rs`
```
pub async fn server(...) -> ... {
// code
let app = Router::new()
...
.nest("/user", user::user_routes::user_routes())
...;
}
```
### WebSockets
Websockets are setup-ed out of the box. Extend websocket functionality by extending the commands
`websocket/messages.rs`
```
pub struct RoomMessage {
pub message: String,
pub room: String,
}
pub enum Command {
...
NewCommand(String)
}
```
```
pub async fn parse_text_messages(...) -> ... {
// code
match command {
...,
Command::NewCommand(v) => {
},
...
}
```
**Authentication**
Websocket auth is implemented through the authorization header
which accepts a bearer token and decodes the token for user id represented by the `sub` payload field
### Secrets
Add your secrets to the `secrets.rs`
```
pub static REDIS_URI: Lazy =
Lazy::new(|| env::var("REDIS_URI").expect("REDIS_URI not found"));
```