Files
uplifting-api/src/main.rs
2024-12-11 01:13:14 -08:00

87 lines
2.4 KiB
Rust

use std::{net::Ipv4Addr, sync::Arc};
use hmac::{Hmac, Mac};
use tokio::net::TcpListener;
use utoipa::OpenApi;
use utoipa_axum::{router::OpenApiRouter, routes};
use utoipa_swagger_ui::SwaggerUi;
// tags
use v1::{auth::AUTH_TAG, exercises::EXERCISES_TAG, muscles::MUSCLES_TAG};
mod v1;
mod structs;
mod state;
mod db;
mod error;
mod util;
mod extractors;
pub(crate) use anyhow::Context;
pub(crate) use axum::extract::{Json, State};
pub(crate) use error::{AnyhowError, AppError, Errors};
pub(crate) use serde::{Deserialize, Serialize};
pub(crate) use state::AppState;
pub(crate) use utoipa::ToSchema;
#[derive(OpenApi)]
#[openapi(
tags(
(name = AUTH_TAG, description = "Authentication API endpoints"),
(name = EXERCISES_TAG, description = "Exercise API endpoints"),
(name = MUSCLES_TAG, description = "Muscle API endpoints"),
// (name = CUSTOMER_TAG, description = "Customer API endpoints"),
// (name = ORDER_TAG, description = "Order API endpoints")
),
)]
struct ApiDoc;
/// Get health of the API.
#[utoipa::path(
get,
path = "/.well-known/health-check",
responses(
(status = OK, description = "Success", body = str, content_type = "text/plain")
)
)]
async fn health_check() -> &'static str {
"ok"
}
#[utoipa::path(
get,
path = "/",
responses(
(status = OK, description = "Success", body = str, content_type = "text/plain")
)
)]
async fn index() -> &'static str {
"ok 200"
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
let port: u16 = std::env::var("PORT").unwrap_or_else(|_| "8080".to_string()).parse()?;
let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "secret".to_string());
let db = db::db().await?;
let state = state::AppState { db: Arc::new(db),
jwt_key: Hmac::new_from_slice(jwt_secret.as_bytes()).context("Failed to create HMAC")?
};
let (router, api) = OpenApiRouter::with_openapi(ApiDoc::openapi())
.routes(routes!(health_check))
.routes(routes!(index))
.with_state(state.clone())
.nest("/api/v1", v1::router(state.clone()))
.split_for_parts();
let router = router.merge(SwaggerUi::new("/docs").url("/docs/openapi.json", api));
println!("Listening on http://localhost:{port}");
let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, port)).await?;
axum::serve(listener, router).await?;
Ok(())
}