Add a better structure in the project
This commit is contained in:
@@ -13,3 +13,6 @@ tokio = { version = "1.47.1", features = ["full", "rt-multi-thread", "signal"] }
|
||||
tower-http = { version = "0.6.6", features = ["trace"] }
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||
|
||||
[features]
|
||||
no-auth = []
|
||||
|
||||
144
README.md
144
README.md
@@ -0,0 +1,144 @@
|
||||
# PureNotify Backend
|
||||
|
||||
This is the backend service for the PureNotify application, written in Rust. It's built to be a high-performance, reliable, and scalable foundation for sending notifications.
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- **Asynchronous:** Built with `tokio` and `axum` for non-blocking I/O and high concurrency.
|
||||
- **Configurable:** Easily configure the application using environment variables.
|
||||
- **Logging:** Integrated structured logging with `tracing` for better observability.
|
||||
- **Graceful Shutdown:** Ensures the server shuts down cleanly without dropping active connections.
|
||||
- **Health Check:** A dedicated endpoint to monitor the service's health.
|
||||
|
||||
## 🛠️ Technologies Used
|
||||
|
||||
- **[Rust](https://www.rust-lang.org/)**: The core programming language.
|
||||
- **[Axum](https://github.com/tokio-rs/axum)**: A web application framework that focuses on ergonomics and modularity.
|
||||
- **[Tokio](https://tokio.rs/)**: An asynchronous runtime for the Rust programming language.
|
||||
- **[Serde](https://serde.rs/)**: A framework for serializing and deserializing Rust data structures efficiently.
|
||||
- **[Dotenvy](https://github.com/dotenv-rs/dotenv)**: For loading environment variables from a `.env` file.
|
||||
- **[Tracing](https://github.com/tokio-rs/tracing)**: A framework for instrumenting Rust programs to collect structured, event-based diagnostic information.
|
||||
|
||||
## ⚙️ Getting Started
|
||||
|
||||
Follow these instructions to get a copy of the project up and running on your local machine for development and testing purposes.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
You need to have the Rust toolchain installed on your system. If you don't have it, you can install it from [rustup.rs](https://rustup.rs/).
|
||||
|
||||
```sh
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
### Installation & Running
|
||||
|
||||
1. **Clone the repository:**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/your-username/purenotify_backend.git
|
||||
cd purenotify_backend
|
||||
```
|
||||
|
||||
2. **Create a `.env` file:**
|
||||
Copy the example environment file to create your own local configuration.
|
||||
|
||||
```sh
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
You can modify the `.env` file to change the server's configuration.
|
||||
|
||||
3. **Build the project:**
|
||||
|
||||
```sh
|
||||
cargo build
|
||||
```
|
||||
|
||||
4. **Run the application:**
|
||||
For development, you can run the project directly with `cargo run`:
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
For a release build, run:
|
||||
```sh
|
||||
cargo run --release
|
||||
```
|
||||
|
||||
The server will start, and you should see log output in your terminal indicating that it's running.
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
The application is configured using environment variables. These can be set in a `.env` file in the project root or directly in your shell.
|
||||
|
||||
- `BIND_ADDRESS`: The IP address and port the server should listen on.
|
||||
- **Default:** `127.0.0.1:3000`
|
||||
- `RUST_LOG`: Controls the log level for the application.
|
||||
- **Example:** `RUST_LOG=info,purenotify_backend=debug` will set the default log level to `info` and the log level for this crate to `debug`.
|
||||
- **Default:** Reads from the environment; if not set, logging may be minimal.
|
||||
|
||||
## API Endpoints
|
||||
|
||||
Here are the available API endpoints for the service.
|
||||
|
||||
### Health Check
|
||||
|
||||
- **Endpoint:** `/health`
|
||||
- **Method:** `GET`
|
||||
- **Description:** Used to verify that the service is running and healthy.
|
||||
- **Success Response:**
|
||||
- **Code:** `200 OK`
|
||||
- **Content:** `{"status": "ok"}`
|
||||
|
||||
#### Example Usage
|
||||
|
||||
You can use `curl` to check the health of the service:
|
||||
|
||||
```sh
|
||||
curl http://127.0.0.1:3000/health
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
|
||||
## 📂 Project Structure
|
||||
|
||||
The project follows a standard Rust project layout. The main application logic is located in the `src/` directory.
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.rs # Application entry point, server setup
|
||||
├── config.rs # Configuration management
|
||||
├── handlers/ # Business logic for handling requests
|
||||
│ └── health/
|
||||
│ └── health.rs
|
||||
├── routes/ # API route definitions
|
||||
│ └── health/
|
||||
│ └── health.rs
|
||||
└── utils/ # Utility functions and shared modules
|
||||
```
|
||||
|
||||
- `main.rs`: Initializes the server, logging, configuration, and wires up the routes.
|
||||
- `config.rs`: Defines the `Config` struct and handles loading configuration from the environment.
|
||||
- `handlers/`: Contains the core logic for each API endpoint. Each handler is responsible for processing a request and returning a response.
|
||||
- `routes/`: Defines the Axum `Router` for different parts of the application. These modules map URL paths to their corresponding handlers.
|
||||
- `utils/`: A place for helper functions or modules that are used across different parts of the application.
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions are welcome! If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.
|
||||
|
||||
1. Fork the repository.
|
||||
2. Create your feature branch (`git checkout -b feature/fooBar`).
|
||||
3. Commit your changes (`git commit -am 'Add some fooBar'`).
|
||||
4. Push to the branch (`git push origin feature/fooBar`).
|
||||
5. Create a new Pull Request.
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::str::FromStr;
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
pub bind_address: SocketAddr,
|
||||
pub database_url: Option<String>,
|
||||
// pub database_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -24,11 +24,11 @@ impl Config {
|
||||
return Err("In no-auth mode, BIND_ADDRESS must be 127.0.0.1".to_string());
|
||||
}
|
||||
|
||||
let database_url = env::var("DATABASE_URL").ok();
|
||||
// let database_url = env::var("DATABASE_URL").ok();
|
||||
|
||||
Ok(Self {
|
||||
bind_address,
|
||||
database_url,
|
||||
// database_url,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// src/health.rs
|
||||
// src/handlers/health/health.rs
|
||||
|
||||
use axum::Json;
|
||||
use axum::http::StatusCode;
|
||||
3
src/handlers/health/mod.rs
Normal file
3
src/handlers/health/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
// src/handlers/health/mod.rs
|
||||
|
||||
pub mod health;
|
||||
3
src/handlers/mod.rs
Normal file
3
src/handlers/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
// src/handlers/mod.rs
|
||||
|
||||
pub mod health;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use std::process::exit;
|
||||
|
||||
use axum::{Router, routing::get};
|
||||
use axum::Router;
|
||||
use dotenvy::dotenv;
|
||||
use tokio::signal;
|
||||
use tower_http::trace::TraceLayer;
|
||||
@@ -10,7 +10,8 @@ use tracing::{error, info};
|
||||
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
|
||||
|
||||
mod config;
|
||||
mod health;
|
||||
mod handlers;
|
||||
mod routes;
|
||||
|
||||
use config::Config;
|
||||
|
||||
@@ -41,7 +42,8 @@ async fn main() {
|
||||
|
||||
// Build the Axum router
|
||||
let app = Router::new()
|
||||
.route("/health", get(health::health))
|
||||
// .nest("/health", routes::health::health::health_routes())
|
||||
.nest("/health", routes::health::health::health_routes())
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
// Run the server
|
||||
|
||||
9
src/routes/health/health.rs
Normal file
9
src/routes/health/health.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
// src/routes/health/health.rs
|
||||
|
||||
use axum::{Router, routing::get};
|
||||
|
||||
use crate::handlers::health::health::health;
|
||||
|
||||
pub fn health_routes() -> Router {
|
||||
Router::new().route("/", get(health))
|
||||
}
|
||||
4
src/routes/health/mod.rs
Normal file
4
src/routes/health/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
// src/routes/health/mod.rs
|
||||
|
||||
pub mod health;
|
||||
|
||||
3
src/routes/mod.rs
Normal file
3
src/routes/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
// src/routes/mod.rs
|
||||
|
||||
pub mod health;
|
||||
Reference in New Issue
Block a user