-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Impl Default for Recipe * Simple construction * Base repository trait * Code organization + nested * With context * POSTGRESgit ap! LFG * formatting * Lints * Fmt
- Loading branch information
Showing
7 changed files
with
123 additions
and
5 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use std::future::Future; | ||
|
||
use uuid::Uuid; | ||
|
||
pub mod recipe; | ||
pub mod services; | ||
|
||
pub trait Repository<T>: Send + Sync { | ||
fn find_by_id(&self, id: Uuid) -> impl Future<Output = Option<T>>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,18 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use sqlx::FromRow; | ||
use uuid::Uuid; | ||
|
||
#[derive(Deserialize, Serialize)] | ||
#[derive(Deserialize, FromRow, Serialize)] | ||
pub struct Recipe { | ||
id: Uuid, | ||
name: String, | ||
} | ||
|
||
impl Default for Recipe { | ||
fn default() -> Self { | ||
Self { | ||
id: Uuid::nil(), | ||
name: "Basic Recipe".to_owned(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use axum::routing::get; | ||
use axum::Router; | ||
|
||
use crate::services::recipes::PostgresRecipeRepository; | ||
|
||
mod recipes; | ||
|
||
#[derive(Clone)] | ||
struct ApplicationContext<T> { | ||
pub repo: T, | ||
} | ||
|
||
pub async fn recipes() -> Router { | ||
let db_username = std::env::var("DB_USERNAME").unwrap_or_else(|_| "postgres".to_string()); | ||
let db_password = std::env::var("DB_PASSWORD").unwrap_or_else(|_| "password1234".to_string()); | ||
let db_host = std::env::var("DB_HOST").unwrap_or_else(|_| "db".to_string()); | ||
let db_port = std::env::var("DB_PORT").unwrap_or_else(|_| "5432".to_string()); | ||
let db_name = std::env::var("DB_NAME").unwrap_or_else(|_| "meal-planner".to_string()); | ||
let db_connection_str = | ||
format!("postgresql://{db_username}:{db_password}@{db_host}:{db_port}/{db_name}"); | ||
|
||
let recipe_context = ApplicationContext { | ||
repo: PostgresRecipeRepository::new(&db_connection_str).await, | ||
}; | ||
|
||
Router::new() | ||
.route("/:id", get(recipes::read_one::<PostgresRecipeRepository>)) | ||
.with_state(recipe_context) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::time::Duration; | ||
|
||
use axum::extract::{Path, State}; | ||
use axum::http::StatusCode; | ||
use axum::Json; | ||
use sqlx::postgres::PgPoolOptions; | ||
use sqlx::{Error, PgPool}; | ||
use uuid::Uuid; | ||
|
||
use crate::recipe::Recipe; | ||
use crate::services::ApplicationContext; | ||
use crate::Repository; | ||
|
||
#[derive(Clone)] | ||
pub(super) struct TestRecipeRepository {} | ||
|
||
#[derive(Clone)] | ||
pub(super) struct PostgresRecipeRepository { | ||
pool: PgPool, | ||
} | ||
|
||
impl PostgresRecipeRepository { | ||
pub(super) async fn new(url: &String) -> Self { | ||
let pool: PgPool = PgPoolOptions::new() | ||
.max_connections(5) | ||
.acquire_timeout(Duration::from_secs(3)) | ||
.connect(&url) | ||
.await | ||
.expect("Can\'t connect to database"); | ||
|
||
Self { pool } | ||
} | ||
} | ||
|
||
impl Repository<Recipe> for PostgresRecipeRepository { | ||
async fn find_by_id(&self, id: Uuid) -> Option<Recipe> { | ||
let result: Result<Recipe, Error> = sqlx::query_as("SELECT * FROM recipes WHERE id = $1") | ||
.bind(id) | ||
.fetch_one(&self.pool) | ||
.await; | ||
|
||
match result { | ||
Ok(recipe) => Some(recipe), | ||
Err(err) => { | ||
dbg!(err); | ||
None | ||
}, | ||
} | ||
} | ||
} | ||
|
||
pub(super) async fn read_one<T>( | ||
State(state): State<ApplicationContext<T>>, | ||
Path(id): Path<Uuid>, | ||
) -> Result<Json<Recipe>, StatusCode> | ||
where | ||
T: Repository<Recipe>, | ||
{ | ||
if let Some(recipe) = state.repo.find_by_id(id).await { | ||
return Ok(Json(recipe)); | ||
} | ||
|
||
Err(StatusCode::NOT_FOUND) | ||
} |