Hello World using functions
#![deny(warnings)] use std::convert::Infallible; use warp::Filter; #[tokio::main] async fn main() { let routes = setup_routes(); warp::serve(routes).run(([127, 0, 0, 1], 3030)).await; } pub fn setup_routes() -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { warp::path!().and(warp::get()).and_then(say_hello) } pub async fn say_hello() -> Result<impl warp::Reply, Infallible> { Ok(warp::reply::html("Hello, <b>World</b>!")) } #[cfg(test)] mod test_hello_using_functions { #[tokio::test] async fn test_hello() { use super::setup_routes; use warp::test::request; use warp::http::StatusCode; let routes = setup_routes(); let response = request() .method("GET") .path("/") .reply(&routes) .await; assert_eq!(response.status(), StatusCode::OK); assert_eq!(response.body(), "Hello, <b>World</b>!"); } #[tokio::test] async fn test_other_path() { use super::setup_routes; use warp::test::request; use warp::http::StatusCode; let routes = setup_routes(); let response = request() .method("GET") .path("/hi") .reply(&routes) .await; assert_eq!(response.status(), StatusCode::NOT_FOUND); assert_eq!(response.body(), ""); } #[tokio::test] async fn test_post_method() { use super::setup_routes; use warp::test::request; use warp::http::StatusCode; let routes = setup_routes(); let response = request() .method("POST") .path("/") .reply(&routes) .await; assert_eq!(response.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(response.body(), "HTTP method not allowed"); } }
In this example we have a function called setup_routes
that creates all the mappings between URL pathes and requst methods (such as GET
and POST
) on one hand and functions that will fulfill those requests on the other hand. In this first example we have only one route that deals with the empty path (or /
if you wish) as defined using the warp::path!()
macro and the GET
request method as defined by the warp::get()
function call.
This request is mapped to the arbitrarily named say_hello
function that will return some HTML using the warp::reply::html
function call.
We can run this example with the following command:
cargo run --example hello_using_functions
Then we can visit http://localhost:3030/
and observe that the response is "Hello, World!". The word World being bold and we don't see the HTML tags.
That's because instead of returning a plain string using Ok("Hello, <b>World</b>!")
, the warp::reply::html
function call set the Content-type
to be
text/html
.
We can easily observe this using curl
in another terminal:
$ curl -i http://localhost:3030/
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 20
date: Mon, 14 Apr 2025 15:41:21 GMT
Hello, <b>World</b>!
We can also check other pathes and observe they return a 404 Not Found
with an empty page:
$ curl -i http://localhost:3030/hi
HTTP/1.1 404 Not Found
content-length: 0
date: Mon, 14 Apr 2025 15:42:02 GMT
Similarily using the POST
method will yield a 405 Method Not Allowed
error with some text:
$ curl -i -X POST http://localhost:3030/
HTTP/1.1 405 Method Not Allowed
content-type: text/plain; charset=utf-8
content-length: 23
date: Mon, 14 Apr 2025 15:43:07 GMT
HTTP method not allowed
Testing
The second part of the file is the test. It tests the application through the route-handler (the Filter in warp terms) so it can test everything besides the web-server itself.
There are 3 test-cases. The first one checking the happy path, when the user accesses the main page with a GET
request.
The other two checks the two other requests that return various error status codes. It might be strange at first to test
invalid requests, but even in a real-world application we'd want to make sure that invalid requests show the expected error
message and not some garbage or some internal information. So it is a good practice to have tests for some invalid requests.
We can run the tests by running the following command:
cargo test --example hello_using_functions
```<style>
footer {
text-align: center;
text-wrap: balance;
margin-top: 5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
footer p {
margin: 0;
}
</style>
<footer><p>Copyright © 2025 • Created with ❤️ by the authors of warp and <a href="https://szabgab.com/">Gabor Szabo</a></p>
</footer>