feat(server): add trailing slash normalization and API root endpoint

- Add tower-http normalize-path feature to handle trailing slashes
- Implement NormalizePathLayer to trim trailing slashes from URLs
- Add GET /api/ endpoint with API description message
- Fix OAuth callback redirect to use /api/profile path
This commit is contained in:
Ryan Walters
2025-11-02 22:51:17 -06:00
parent 83e389d789
commit 52dee3eee4
3 changed files with 10 additions and 4 deletions

View File

@@ -44,7 +44,7 @@ jsonwebtoken = { version = "9.3", default-features = false }
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json"] }
tracing-futures = { version = "0.2.5", features = ["tokio"] }
tower-http = { version = "0.6", features = ["trace", "fs"] }
tower-http = { version = "0.6", features = ["trace", "fs", "normalize-path"] }
time = { version = "0.3", features = ["macros", "formatting"] }
yansi = "1"
s3-tokio = { version = "0.39.6", default-features = false }

View File

@@ -7,6 +7,7 @@ use std::sync::Arc;
use std::time::Duration;
use tokio::sync::{Notify, RwLock};
use tokio::task::JoinHandle;
use tower_http::normalize_path::NormalizePathLayer;
use tower_http::services::{ServeDir, ServeFile};
use tracing::info_span;
@@ -191,7 +192,12 @@ pub fn create_router(app_state: AppState) -> Router {
.layer(axum::middleware::from_fn(inject_server_header));
// Create main router with API routes nested under /api
let router = Router::new().nest("/api", api_router);
let router = Router::new()
.route(
"/api/",
get(|| async { "Pac-Man API Server. Visit /api/auth/github to start OAuth flow." }),
)
.nest("/api", api_router);
// Add static file serving if the directory exists
let router = if static_path.exists() {
@@ -203,7 +209,7 @@ pub fn create_router(app_state: AppState) -> Router {
};
// Add tracing layer to the entire router
router.layer(
router.layer(NormalizePathLayer::trim_trailing_slash()).layer(
tower_http::trace::TraceLayer::new_for_http()
.make_span_with(make_span)
.on_request(|_request: &axum::http::Request<axum::body::Body>, _span: &tracing::Span| {

View File

@@ -175,7 +175,7 @@ pub async fn oauth_callback_handler(
});
}
(StatusCode::FOUND, Redirect::to("/profile")).into_response()
(StatusCode::FOUND, Redirect::to("/api/profile")).into_response()
}
/// Handles the request to the profile endpoint.