Add initial services

This commit is contained in:
Kasper Juul Hermansen 2022-10-03 23:00:31 +02:00
parent b01b33f7d1
commit 6234cf18e8
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
22 changed files with 932 additions and 91 deletions

726
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
[workspace]
members = ["como_bin", "como_core", "como_domain"]
members = ["como_bin", "como_core", "como_domain", "como_infrastructure"]

View File

@ -6,6 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
como_core = { path = "../como_core" }
como_domain = { path = "../como_domain" }
como_infrastructure = { path = "../como_infrastructure" }
async-graphql = "4.0.6"
async-graphql-axum = "*"
axum = "0.5.13"

View File

@ -1,7 +1,6 @@
use async_graphql::{Context, EmptySubscription, Object, Schema, SimpleObject};
use async_graphql::{Context, EmptySubscription, Object, Schema};
use uuid::Uuid;
use como_domain::item::{requests::CreateItemDto, responses::CreatedItemDto};
use crate::services::users_service::UserService;
@ -40,67 +39,19 @@ impl MutationRoot {
Ok(user_id)
}
async fn create_item(
&self,
ctx: &Context<'_>,
item: CreateItemDto,
) -> anyhow::Result<CreatedItemDto> {
let services_register = ctx.data_unchecked::<ServiceRegister>()
}
}
pub struct QueryRoot;
#[Object]
impl QueryRoot {
async fn get_upcoming(&self, _ctx: &Context<'_>) -> Vec<Event> {
vec![Event::new(
None,
"Some-name".into(),
None,
None,
EventDate::new(2022, 08, 08, 23, 51),
)]
}
}
#[derive(SimpleObject)]
pub struct Event {
pub id: String,
pub name: String,
pub description: Option<Vec<String>>,
pub location: Option<String>,
pub date: EventDate,
}
impl Event {
pub fn new(
id: Option<String>,
name: String,
description: Option<Vec<String>>,
location: Option<String>,
date: EventDate,
) -> Self {
Self {
id: id.unwrap_or_else(|| Uuid::new_v4().to_string()),
name,
description,
location,
date,
}
}
}
#[derive(SimpleObject)]
pub struct EventDate {
pub year: u32,
pub month: u32,
pub day: u32,
pub hour: u32,
pub minute: u32,
}
impl EventDate {
pub fn new(year: u32, month: u32, day: u32, hour: u32, minute: u32) -> Self {
Self {
year,
month,
day,
hour,
minute,
}
}
async fn get_upcoming(&self, _ctx: &Context<'_>) -> Vec<Event> {}
}

View File

@ -41,6 +41,7 @@ async fn graphql_handler(
req: GraphQLRequest,
) -> Result<GraphQLResponse, StatusCode> {
let req = req.into_inner();
//if let Some(user_id) = session.get::<String>("userId") {
// req = req.data(user_id);
return Ok(schema.execute(req).await.into());

View File

@ -6,3 +6,25 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1", features = ["full"] }
axum = "0.5.1"
# utilty crates
serde = { version = "1.0.136", features = ["derive"] }
sqlx = { version = "0.5", features = [
"runtime-tokio-rustls",
"postgres",
"time",
] }
serde_json = "1.0.81"
dotenv = "0.15.0"
tracing = "0.1"
tracing-subscriber = "0.3"
anyhow = "1"
validator = { version = "0.15", features = ["derive"] }
async-trait = "0.1"
thiserror = "1"
rust-argon2 = "1.0"
clap = { version = "3", features = ["derive", "env"] }
mockall = "0.11.1"
time = "0.2"

View File

@ -0,0 +1,8 @@
use std::sync::Arc;
use async_trait::async_trait;
pub type DynItemService = Arc<dyn ItemService + Send + Sync>;
#[async_trait]
pub trait ItemService {}

View File

@ -1,2 +1,3 @@
pub mod items;
pub mod projects;
pub mod users;

View File

@ -0,0 +1,8 @@
use std::sync::Arc;
use async_trait::async_trait;
pub type DynProjectService = Arc<dyn ProjectService + Send + Sync>;
#[async_trait]
pub trait ProjectService {}

View File

@ -0,0 +1,8 @@
use std::sync::Arc;
use async_trait::async_trait;
pub type DynUserService = Arc<dyn UserService + Send + Sync>;
#[async_trait]
pub trait UserService {}

View File

@ -0,0 +1,36 @@
[package]
name = "como_infrastructure"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
como_core = { path = "../como_core" }
como_domain = { path = "../como_domain" }
async-graphql = "4.0.6"
async-graphql-axum = "*"
axum = "0.5.13"
axum-extra = { version = "*", features = ["cookie", "cookie-private"] }
axum-sessions = { version = "*" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.68"
tokio = { version = "1.20.1", features = ["full"] }
uuid = { version = "1.1.2", features = ["v4", "fast-rng"] }
sqlx = { version = "0.6", features = [
"runtime-tokio-rustls",
"postgres",
"migrate",
"uuid",
"offline",
] }
anyhow = "1.0.60"
dotenv = "0.15.0"
tracing = "0.1.36"
tracing-subscriber = { version = "0.3.15", features = ["env-filter"] }
tower-http = { version = "0.3.4", features = ["full"] }
argon2 = "0.4"
rand_core = { version = "0.6", features = ["std"] }
cookie = { version = "0.16", features = ["secure", "percent-encode"] }
clap = { version = "3", features = ["derive", "env"] }

View File

@ -0,0 +1,18 @@
#[derive(clap::Parser)]
pub struct AppConfig {
#[clap(long, env)]
pub database_url: String,
#[clap(long, env)]
pub rust_log: String,
#[clap(long, env)]
pub token_secret: String,
#[clap(long, env)]
pub port: u32,
#[clap(long, env)]
pub run_migrations: bool,
#[clap(long, env)]
pub seed: bool,
#[clap(long, env)]
pub cors_origin: String,
}

View File

@ -0,0 +1,33 @@
use anyhow::Context;
use sqlx::{postgres::PgPoolOptions, Pool, Postgres};
use tracing::log::info;
pub type ConnectionPool = Pool<Postgres>;
pub struct ConnectionPoolManager;
impl ConnectionPoolManager {
pub async fn new_pool(
connection_string: &str,
run_migrations: bool,
) -> anyhow::Result<ConnectionPool> {
info!("initializing the database connection pool");
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(connection_string)
.await
.context("error while initializing the database connection pool")?;
if run_migrations {
info!("migrations enabled");
info!("migrating database");
sqlx::migrate!()
.run(&pool)
.await
.context("error while running database migrations");
}
Ok(pool)
}
}

View File

@ -0,0 +1,5 @@
pub mod configs;
pub mod database;
pub mod register;
pub mod repositories;
pub mod services;

View File

@ -0,0 +1,38 @@
use std::sync::Arc;
use como_core::{items::DynItemService, projects::DynProjectService, users::DynUserService};
use tracing::log::info;
use crate::{
configs::AppConfig,
database::ConnectionPool,
services::{
item_service::DefaultItemService, project_service::DefaultProjectService,
user_service::DefaultUserService,
},
};
#[derive(Clone)]
pub struct ServiceRegister {
pub item_service: DynItemService,
pub project_service: DynProjectService,
pub user_service: DynUserService,
}
impl ServiceRegister {
pub fn new(_pool: ConnectionPool, _config: AppConfig) -> Self {
info!("creating services");
let item_service = Arc::new(DefaultItemService::new()) as DynItemService;
let project_service = Arc::new(DefaultProjectService::new()) as DynProjectService;
let user_service = Arc::new(DefaultUserService::new()) as DynUserService;
info!("services created succesfully");
return Self {
item_service,
user_service,
project_service,
};
}
}

View File

@ -0,0 +1,11 @@
use como_core::items::ItemService;
pub struct DefaultItemService {}
impl DefaultItemService {
pub fn new() -> Self {
Self {}
}
}
impl ItemService for DefaultItemService {}

View File

@ -0,0 +1,3 @@
pub mod item_service;
pub mod project_service;
pub mod user_service;

View File

@ -0,0 +1,11 @@
use como_core::projects::ProjectService;
pub struct DefaultProjectService {}
impl DefaultProjectService {
pub fn new() -> Self {
Self {}
}
}
impl ProjectService for DefaultProjectService {}

View File

@ -0,0 +1,11 @@
use como_core::users::UserService;
pub struct DefaultUserService {}
impl DefaultUserService {
pub fn new() -> Self {
Self {}
}
}
impl UserService for DefaultUserService {}

View File

@ -2,5 +2,5 @@
export $(cat .env | xargs)
cargo sqlx migrate run --source como_bin/db/migrations --database-url=$DATABASE_URL
cargo sqlx migrate run --source como_infrastructure/migrations --database-url=$DATABASE_URL