mirror of
https://github.com/kristoferssolo/zero2prod.git
synced 2025-10-21 20:10:40 +00:00
feat(config): add config file
This commit is contained in:
parent
5ce9b4a766
commit
938bb7d071
1285
Cargo.lock
generated
1285
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,9 @@ name = "zero2prod"
|
||||
|
||||
[dependencies]
|
||||
axum = "0.7"
|
||||
config = "0.14"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio", "tls-rustls", "macros", "postgres", "uuid", "chrono", "migrate"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
38
src/configuation.rs
Normal file
38
src/configuation.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Settings {
|
||||
pub database: DatabaseSettings,
|
||||
pub application_port: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct DatabaseSettings {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub port: u16,
|
||||
pub host: String,
|
||||
pub database_name: String,
|
||||
}
|
||||
|
||||
impl Display for DatabaseSettings {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"postgres://{}:{}@{}:{}/{}",
|
||||
self.username, self.password, self.host, self.port, self.database_name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_configuration() -> Result<Settings, config::ConfigError> {
|
||||
let settings = config::Config::builder()
|
||||
.add_source(config::File::new(
|
||||
"configuration.toml",
|
||||
config::FileFormat::Toml,
|
||||
))
|
||||
.build()?;
|
||||
settings.try_deserialize::<Settings>()
|
||||
}
|
||||
40
src/lib.rs
40
src/lib.rs
@ -1,37 +1,3 @@
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Form, Router,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn app() -> Router {
|
||||
Router::new()
|
||||
.route("/", get(root))
|
||||
.route("/:name", get(greet))
|
||||
.route("/health_check", get(health_check))
|
||||
.route("/subscribtions", post(subscribe))
|
||||
}
|
||||
|
||||
async fn root() -> impl IntoResponse {
|
||||
"Hello, world!"
|
||||
}
|
||||
|
||||
async fn greet(Path(name): Path<String>) -> impl IntoResponse {
|
||||
format!("Hello, {name}!")
|
||||
}
|
||||
async fn health_check() -> impl IntoResponse {
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct FormData {
|
||||
name: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
async fn subscribe(Form(form): Form<FormData>) -> impl IntoResponse {
|
||||
StatusCode::OK
|
||||
}
|
||||
pub mod configuation;
|
||||
pub mod routes;
|
||||
pub mod startup;
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use tokio::net::TcpListener;
|
||||
use zero2prod::{configuation::get_configuration, routes::route};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
|
||||
async fn main() -> Result<(), std::io::Error> {
|
||||
let configuation = get_configuration().expect("Failed to read configuation.");
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], configuation.application_port));
|
||||
let listener = TcpListener::bind(addr)
|
||||
.await
|
||||
.expect("Failed to bind random port");
|
||||
axum::serve(listener, zero2prod::app()).await.unwrap();
|
||||
axum::serve(listener, route()).await
|
||||
}
|
||||
|
||||
5
src/routes/health_check.rs
Normal file
5
src/routes/health_check.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use axum::{http::StatusCode, response::IntoResponse};
|
||||
|
||||
pub async fn health_check() -> impl IntoResponse {
|
||||
StatusCode::OK
|
||||
}
|
||||
15
src/routes/mod.rs
Normal file
15
src/routes/mod.rs
Normal file
@ -0,0 +1,15 @@
|
||||
mod health_check;
|
||||
mod subscibtions;
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
Router,
|
||||
};
|
||||
|
||||
pub use health_check::*;
|
||||
pub use subscibtions::*;
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/health_check", get(health_check))
|
||||
.route("/subscribtions", post(subscribe))
|
||||
}
|
||||
11
src/routes/subscibtions.rs
Normal file
11
src/routes/subscibtions.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use axum::{http::StatusCode, response::IntoResponse, Form};
|
||||
use serde::Deserialize;
|
||||
#[derive(Deserialize)]
|
||||
pub struct FormData {
|
||||
name: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
pub async fn subscribe(Form(form): Form<FormData>) -> impl IntoResponse {
|
||||
StatusCode::OK
|
||||
}
|
||||
2
src/startup.rs
Normal file
2
src/startup.rs
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use reqwest::Client;
|
||||
use sqlx::{Connection, PgConnection};
|
||||
use tokio::net::TcpListener;
|
||||
use zero2prod::{configuation::get_configuration, routes::route};
|
||||
|
||||
#[tokio::test]
|
||||
async fn health_check() {
|
||||
@ -19,6 +21,11 @@ async fn health_check() {
|
||||
#[tokio::test]
|
||||
async fn subscribe_returns_200_for_valid_form_data() {
|
||||
let address = spawn_app().await;
|
||||
let configuration = get_configuration().expect("Failed to read configuration.");
|
||||
let db_url = configuration.database.to_string();
|
||||
let connection = PgConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("Failed to connect to Postgres.");
|
||||
let client = Client::new();
|
||||
|
||||
let body = "name=kristofers%20solo&email=dev%40kristofers.solo";
|
||||
@ -67,6 +74,6 @@ async fn spawn_app() -> String {
|
||||
.await
|
||||
.expect("Failed to bind random port");
|
||||
let port = listener.local_addr().unwrap().port();
|
||||
let _ = tokio::spawn(async move { axum::serve(listener, zero2prod::app()).await.unwrap() });
|
||||
let _ = tokio::spawn(async move { axum::serve(listener, route()).await.unwrap() });
|
||||
format!("http://127.0.0.1:{}", port)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user