app-lookup / src /main.rs
lljz66's picture
Upload src/main.rs
4a80e91 verified
Raw
History Blame Contribute Delete
2 kB
mod config;
mod models;
mod search;
use axum::{
extract::Query,
http::Method,
routing::get,
Json, Router,
};
use config::Config;
use models::{SearchQuery, SearchResponse};
use reqwest::Client;
use std::net::SocketAddr;
use tower_http::cors::{Any, CorsLayer};
use tower_http::services::ServeDir;
use tracing::info;
#[derive(Clone)]
struct AppState {
client: Client,
config: Config,
}
#[tokio::main]
async fn main() {
let config = Config::from_env();
tracing_subscriber::fmt()
.with_env_filter(&config.log_level)
.init();
info!("Starting App Lookup Rust backend...");
let client = Client::builder()
.timeout(std::time::Duration::from_secs(config.http_timeout_secs))
.build()
.expect("Failed to build HTTP client");
let state = AppState {
client,
config: config.clone(),
};
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods([Method::GET, Method::POST])
.allow_headers(Any);
let app = Router::new()
.route("/api/search", get(handle_search))
.nest_service("/", ServeDir::new("static"))
.layer(cors)
.with_state(state);
let addr = SocketAddr::new(
config.host.parse().unwrap(),
config.port,
);
info!("Listening on {}", addr);
let listener = tokio::net::TcpListener::bind(addr)
.await
.expect("Failed to bind");
axum::serve(listener, app)
.await
.expect("Server error");
}
async fn handle_search(
state: axum::extract::State<AppState>,
Query(params): Query<SearchQuery>,
) -> Json<SearchResponse> {
info!("API request | q={} | store={}", params.q, params.store);
let results = search::orchestrator::search_all(
&state.client,
&params.q,
&params.store,
params.limit,
)
.await;
Json(SearchResponse {
query: params.q,
count: results.len(),
results,
})
}