mirror of
				https://github.com/tokio-rs/axum.git
				synced 2025-11-04 07:23:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
use awebframework::{prelude::*, routing::BoxRoute};
 | 
						|
use tower_http::trace::TraceLayer;
 | 
						|
 | 
						|
#[tokio::main]
 | 
						|
async fn main() {
 | 
						|
    tracing_subscriber::fmt::init();
 | 
						|
 | 
						|
    let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 3000));
 | 
						|
 | 
						|
    tracing::debug!("listening on {}", addr);
 | 
						|
 | 
						|
    hyper::Server::bind(&addr)
 | 
						|
        .serve(app().into_make_service())
 | 
						|
        .await
 | 
						|
        .unwrap();
 | 
						|
}
 | 
						|
 | 
						|
/// Having a function that produces our app makes it easy to call it from tests
 | 
						|
/// without having to create an HTTP server.
 | 
						|
#[allow(dead_code)]
 | 
						|
fn app() -> BoxRoute<Body> {
 | 
						|
    route("/", get(|| async { "Hello, World!" }))
 | 
						|
        .route(
 | 
						|
            "/json",
 | 
						|
            post(|payload: extract::Json<serde_json::Value>| async move {
 | 
						|
                response::Json(serde_json::json!({ "data": payload.0 }))
 | 
						|
            }),
 | 
						|
        )
 | 
						|
        // We can still add middleware
 | 
						|
        .layer(TraceLayer::new_for_http())
 | 
						|
        .boxed()
 | 
						|
}
 | 
						|
 | 
						|
#[cfg(test)]
 | 
						|
mod tests {
 | 
						|
    use super::*;
 | 
						|
    use http::StatusCode;
 | 
						|
    use serde_json::{json, Value};
 | 
						|
    use tower::ServiceExt; // for `app.oneshot()`
 | 
						|
 | 
						|
    #[tokio::test]
 | 
						|
    async fn hello_world() {
 | 
						|
        let app = app();
 | 
						|
 | 
						|
        // `BoxRoute<Body>` implements `tower::Service<Request<Body>>` so we can
 | 
						|
        // call it like any tower service, no need to run an HTTP server.
 | 
						|
        let response = app
 | 
						|
            .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap())
 | 
						|
            .await
 | 
						|
            .unwrap();
 | 
						|
 | 
						|
        assert_eq!(response.status(), StatusCode::OK);
 | 
						|
 | 
						|
        let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
 | 
						|
        assert_eq!(&body[..], b"Hello, World!");
 | 
						|
    }
 | 
						|
 | 
						|
    #[tokio::test]
 | 
						|
    async fn json() {
 | 
						|
        let app = app();
 | 
						|
 | 
						|
        let response = app
 | 
						|
            .oneshot(
 | 
						|
                Request::builder()
 | 
						|
                    .method(http::Method::POST)
 | 
						|
                    .uri("/json")
 | 
						|
                    .header(http::header::CONTENT_TYPE, "application/json")
 | 
						|
                    .body(Body::from(
 | 
						|
                        serde_json::to_vec(&json!([1, 2, 3, 4])).unwrap(),
 | 
						|
                    ))
 | 
						|
                    .unwrap(),
 | 
						|
            )
 | 
						|
            .await
 | 
						|
            .unwrap();
 | 
						|
 | 
						|
        assert_eq!(response.status(), StatusCode::OK);
 | 
						|
 | 
						|
        let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
 | 
						|
        let body: Value = serde_json::from_slice(&body).unwrap();
 | 
						|
        assert_eq!(body, json!({ "data": [1, 2, 3, 4] }));
 | 
						|
    }
 | 
						|
 | 
						|
    #[tokio::test]
 | 
						|
    async fn not_found() {
 | 
						|
        let app = app();
 | 
						|
 | 
						|
        let response = app
 | 
						|
            .oneshot(
 | 
						|
                Request::builder()
 | 
						|
                    .uri("/does-not-exist")
 | 
						|
                    .body(Body::empty())
 | 
						|
                    .unwrap(),
 | 
						|
            )
 | 
						|
            .await
 | 
						|
            .unwrap();
 | 
						|
 | 
						|
        assert_eq!(response.status(), StatusCode::NOT_FOUND);
 | 
						|
        let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
 | 
						|
        assert!(body.is_empty());
 | 
						|
    }
 | 
						|
}
 |