mirror of
https://github.com/ruvnet/RuView
synced 2026-08-05 19:41:44 +00:00
d803bfe2b1
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
104 lines
3.1 KiB
Rust
104 lines
3.1 KiB
Rust
use axum::{
|
|
routing::{delete, get, post},
|
|
Router,
|
|
};
|
|
use tower::ServiceBuilder;
|
|
use tower_http::{
|
|
compression::CompressionLayer,
|
|
cors::CorsLayer,
|
|
trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer},
|
|
};
|
|
use tracing::Level;
|
|
|
|
use super::{
|
|
handlers::{
|
|
convert_document, delete_pdf_job, get_health, get_ocr_results, get_ocr_usage,
|
|
get_pdf_status, process_latex, process_pdf, process_strokes, process_text,
|
|
stream_pdf_results,
|
|
},
|
|
middleware::{auth_middleware, rate_limit_middleware},
|
|
state::AppState,
|
|
};
|
|
|
|
/// Create the main application router with all routes and middleware
|
|
pub fn router(state: AppState) -> Router {
|
|
// API v3 routes
|
|
let api_routes = Router::new()
|
|
// Image processing
|
|
.route("/v3/text", post(process_text))
|
|
// Digital ink processing
|
|
.route("/v3/strokes", post(process_strokes))
|
|
// Legacy equation processing
|
|
.route("/v3/latex", post(process_latex))
|
|
// Async PDF processing
|
|
.route("/v3/pdf", post(process_pdf))
|
|
.route("/v3/pdf/:id", get(get_pdf_status))
|
|
.route("/v3/pdf/:id", delete(delete_pdf_job))
|
|
.route("/v3/pdf/:id/stream", get(stream_pdf_results))
|
|
// Document conversion
|
|
.route("/v3/converter", post(convert_document))
|
|
// History and usage
|
|
.route("/v3/ocr-results", get(get_ocr_results))
|
|
.route("/v3/ocr-usage", get(get_ocr_usage))
|
|
// Apply auth and rate limiting to all API routes
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
.layer(axum::middleware::from_fn_with_state(
|
|
state.clone(),
|
|
auth_middleware,
|
|
))
|
|
.layer(axum::middleware::from_fn_with_state(
|
|
state.clone(),
|
|
rate_limit_middleware,
|
|
)),
|
|
);
|
|
|
|
// Health check (no auth required)
|
|
let health_routes = Router::new().route("/health", get(get_health));
|
|
|
|
// Combine all routes
|
|
Router::new()
|
|
.merge(api_routes)
|
|
.merge(health_routes)
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
// Tracing layer
|
|
.layer(
|
|
TraceLayer::new_for_http()
|
|
.make_span_with(DefaultMakeSpan::new().level(Level::INFO))
|
|
.on_response(DefaultOnResponse::new().level(Level::INFO)),
|
|
)
|
|
// CORS layer
|
|
.layer(CorsLayer::permissive())
|
|
// Compression layer
|
|
.layer(CompressionLayer::new()),
|
|
)
|
|
.with_state(state)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use axum::body::Body;
|
|
use axum::http::{Request, StatusCode};
|
|
use tower::ServiceExt;
|
|
|
|
#[tokio::test]
|
|
async fn test_health_endpoint() {
|
|
let state = AppState::new();
|
|
let app = router(state);
|
|
|
|
let response = app
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/health")
|
|
.body(Body::empty())
|
|
.unwrap(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
}
|
|
}
|