feat(api): added basic API infrastructure

This commit is contained in:
antifallobst 2024-03-18 22:58:45 +01:00
parent 19c7879261
commit 0bb3e456be
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
6 changed files with 84 additions and 5 deletions

View File

@ -15,4 +15,4 @@ dotenvy = "0.15.7"
compile-time-run = "0.2.12" compile-time-run = "0.2.12"
actix-web = "4.5.1" actix-web = "4.5.1"
sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-native-tls"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-native-tls", "mysql"] }

6
src/api/endpoints.rs Normal file
View File

@ -0,0 +1,6 @@
use actix_web::{post, HttpResponse, Responder};
#[post("/account/register")]
pub async fn account_register() -> impl Responder {
HttpResponse::Ok()
}

25
src/api/mod.rs Normal file
View File

@ -0,0 +1,25 @@
use crate::backend::Backend;
use crate::config::Config;
use actix_web::{web, App, HttpServer};
use anyhow::Result;
use log::info;
mod endpoints;
pub async fn start(config: &Config, backend: Backend) -> Result<()> {
let server = HttpServer::new(move || {
App::new()
.app_data(web::Data::new(backend.clone()))
.service(endpoints::account_register)
})
.bind((config.addr.as_str(), config.port))?;
if let Some(threads) = config.threads {
server.workers(threads as usize).run().await?;
} else {
server.run().await?;
}
info!("API online");
Ok(())
}

35
src/backend/mod.rs Normal file
View File

@ -0,0 +1,35 @@
use crate::config::Config;
use anyhow::Result;
use log::info;
use sqlx::MySqlPool;
#[derive(Debug, Clone)]
pub struct Backend {
pool: MySqlPool,
}
pub async fn start(config: &Config) -> Result<Backend> {
let pool = MySqlPool::connect(config.database.as_str()).await?.into();
sqlx::query!(
r#"CREATE TABLE IF NOT EXISTS Users (
username VARCHAR(32) NOT NULL PRIMARY KEY,
password VARCHAR(98) NOT NULL
);"#
)
.execute(&pool)
.await?;
sqlx::query!(
r#"CREATE TABLE IF NOT EXISTS Relays (
id BINARY(16) NOT NULL PRIMARY KEY,
secret VARCHAR(98) NOT NULL
);"#
)
.execute(&pool)
.await?;
info!("Backend initialized");
Ok(Backend { pool })
}

View File

@ -4,9 +4,10 @@ use std::env;
#[derive(Debug)] #[derive(Debug)]
pub struct Config { pub struct Config {
addr: String, pub addr: String,
port: u16, pub port: u16,
database: String, pub database: String,
pub threads: Option<u16>,
} }
impl Config { impl Config {
@ -27,7 +28,14 @@ impl Config {
database: match env::var("CR_DATABASE") { database: match env::var("CR_DATABASE") {
Ok(db) => db, Ok(db) => db,
Err(_) => bail!("The environment variable CR_DATABASE is required!"), Err(_) => bail!("The environment variable CR_DATABASE is required!"),
} },
threads: match env::var("CR_THREADS") {
Ok(str) => match str.parse() {
Ok(threads) => Some(threads),
Err(_) => bail!("Failed to parse environment variable CR_THREAD: '{str}' is not a valid number!"),
},
Err(_) => None
},
}) })
} }
} }

View File

@ -1,3 +1,5 @@
mod api;
mod backend;
mod config; mod config;
use anyhow::Result; use anyhow::Result;
@ -21,5 +23,8 @@ async fn main() -> Result<()> {
println!("{config:#?}"); println!("{config:#?}");
let backend = backend::start(&config).await?;
api::start(&config, backend).await?;
Ok(()) Ok(())
} }