feat: implement surrealdb and redis

This commit is contained in:
Maulana Sodiqin
2025-02-25 02:00:19 +07:00
parent 9abab01b9c
commit 44de53a49d
18 changed files with 2501 additions and 137 deletions
+8 -9
View File
@@ -1,15 +1,14 @@
use axum::{routing::get, Router};
use v1::auth_router;
use crate::{AppState, RedisClient, SurrealClient};
use axum::{Extension, Router};
pub mod v1;
pub mod v2;
pub async fn apps() -> Router {
let v1_routes = Router::new()
.nest("/auth", auth_router())
.route("/", get(|| async { "Comming Soon v1" }));
pub async fn apps(surrealdb: SurrealClient, redisdb: RedisClient) -> Router {
let state = AppState { surrealdb, redisdb };
let v2_routes = Router::new().route("/", get(|| async { "Comming Soon v2" }));
Router::new().nest("/v1", v1_routes).nest("/v2", v2_routes)
Router::new()
.nest("/v1", v1::routes().await)
.nest("/v2", v2::routes().await)
.layer(Extension(state))
}
+9 -4
View File
@@ -1,6 +1,11 @@
use super::{mutation_login, AuthLoginRequestDto};
use axum::{response::Response, Json};
use axum::{response::IntoResponse, Extension, Json};
pub async fn post_login(Json(payload): Json<AuthLoginRequestDto>) -> Response {
mutation_login(payload).await
use super::{mutation_login, AuthLoginRequestDto};
use crate::AppState;
pub async fn post_login(
Extension(state): Extension<AppState>,
Json(payload): Json<AuthLoginRequestDto>,
) -> impl IntoResponse {
mutation_login(payload, &state).await
}
+24 -2
View File
@@ -1,8 +1,30 @@
use super::auth_dto::AuthLoginRequestDto;
use crate::{success_response, ResponseSuccessDto};
use crate::{success_response, AppState, ResponseSuccessDto};
use axum::response::Response;
pub async fn mutation_login(params: AuthLoginRequestDto) -> Response {
const USERS_KEY: &str = "users";
pub async fn mutation_login(
params: AuthLoginRequestDto,
state: &AppState,
) -> Response {
let _users: Option<AuthLoginRequestDto> = state
.surrealdb
.select((USERS_KEY, &*params.email))
.await
.unwrap();
let mut redis_conn = state
.redisdb
.get_connection()
.expect("failed to get connection");
redis::cmd("SET")
.arg("some_key")
.arg("some_value")
.query::<()>(&mut redis_conn)
.expect("failed to set value");
let response = ResponseSuccessDto {
data: AuthLoginRequestDto {
email: params.email,
+5 -1
View File
@@ -1,3 +1,7 @@
use axum::Router;
pub mod auth;
pub use auth::*;
pub async fn routes() -> Router {
Router::new().nest("/auth", auth::auth_router())
}
View File
View File
+9
View File
@@ -0,0 +1,9 @@
use axum::{response::IntoResponse, routing::post, Router};
async fn dummy_login() -> impl IntoResponse {
"Logged in successfully"
}
pub fn auth_router() -> Router {
Router::new().route("/login", post(dummy_login))
}
+9
View File
@@ -0,0 +1,9 @@
use axum::Router;
pub mod auth;
pub use auth::*;
pub async fn routes() -> Router {
let public_routes = Router::new().nest("/auth", auth::auth_router());
Router::new().merge(public_routes)
}
+10
View File
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use surrealdb::{engine::remote::ws::Client, Surreal};
use utoipa::{IntoParams, ToSchema};
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
@@ -35,3 +36,12 @@ pub struct ResponseListSuccessDto<T: Serialize> {
pub data: T,
pub meta: Option<MetaResponseDto>,
}
pub type SurrealClient = Surreal<Client>;
pub type RedisClient = redis::Client;
#[derive(Clone)]
pub struct AppState {
pub surrealdb: SurrealClient,
pub redisdb: RedisClient,
}
+27
View File
@@ -0,0 +1,27 @@
pub mod error {
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::response::Response;
use axum::Json;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("database error")]
Db,
}
impl IntoResponse for Error {
fn into_response(self) -> Response {
(StatusCode::INTERNAL_SERVER_ERROR, Json(self.to_string()))
.into_response()
}
}
impl From<surrealdb::Error> for Error {
fn from(error: surrealdb::Error) -> Self {
eprintln!("{error}");
Self::Db
}
}
}
+2
View File
@@ -1,3 +1,5 @@
pub mod common_dto;
pub mod error_dto;
pub use common_dto::*;
pub use error_dto::*;
+11 -3
View File
@@ -3,21 +3,29 @@ use std::env;
use std::{future::Future, net::SocketAddr};
use tokio::net::TcpListener;
use crate::{redisdb_init, RedisClient};
use crate::{surrealdb_init, SurrealClient};
pub async fn axum_init<F, Fut>(router_fn: F)
where
F: Fn() -> Fut,
F: FnOnce(SurrealClient, RedisClient) -> Fut,
Fut: Future<Output = Router>,
{
let router = router_fn().await;
let surrealdb = surrealdb_init().await.expect("Failed surrealdb");
let redisdb = redisdb_init().await.expect("Failed redisdb");
let router = router_fn(surrealdb, redisdb).await;
let addr = SocketAddr::from((
[0, 0, 0, 0],
env::var("PORT")
.unwrap_or("3000".to_string())
.unwrap_or_else(|_| "3000".to_string())
.parse()
.unwrap(),
));
let listener = TcpListener::bind(&addr).await.unwrap();
println!("Listening on http://{}", addr);
match serve(listener, router).await {
Ok(_) => println!("Server stopped gracefully."),
Err(err) => println!("Server encountered an error: {}", err),
+2
View File
@@ -4,6 +4,7 @@ pub mod jsonwebtoken;
pub mod lettre;
pub mod redis;
pub mod seaorm;
pub mod surrealdb;
pub use argon::*;
pub use axum::*;
@@ -11,3 +12,4 @@ pub use jsonwebtoken::*;
pub use lettre::*;
pub use redis::*;
pub use seaorm::*;
pub use surrealdb::*;
+7 -11
View File
@@ -1,20 +1,16 @@
use redis::Client;
use redis::RedisResult;
use std::env;
use redis::Client;
pub fn db_redis() -> redis::Connection {
let host_name = env::var("REDIS_HOSTNAME").unwrap_or("localhost".to_string());
pub async fn redisdb_init() -> RedisResult<Client> {
let host_name =
env::var("REDIS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string());
let uri_scheme = if env::var("IS_TLS").is_ok() {
"rediss"
} else {
"redis"
};
let url = format!("{}://{}", uri_scheme, host_name);
Client::open(url)
.expect("Invalid connection URL")
.get_connection()
.expect("Failed to connect to Redis")
let client = Client::open(url)?;
Ok(client)
}
+11
View File
@@ -0,0 +1,11 @@
use surrealdb::engine::remote::ws::{Client, Ws};
use surrealdb::{Result, Surreal};
use crate::SurrealClient;
pub async fn surrealdb_init() -> Result<SurrealClient> {
let db = Surreal::<Client>::init();
db.connect::<Ws>("ws://localhost:8000").await?;
db.use_ns("test").use_db("test").await?;
Ok(db)
}
+2 -2
View File
@@ -1,6 +1,6 @@
use imphnen_cms_be::{apps, libs::axum_init};
use imphnen_cms_be::{apps, axum_init};
#[tokio::main]
async fn main() {
axum_init(apps).await;
axum_init(|db, redis| async { apps(db, redis).await }).await;
}