Skip to content
Go back

Building Web API's With Rust 2

Published:  at  03:06 PM

Following the first post around hyper.rs and getting a basic server running, this changes a little to add routing capabilities using the library reset_router.

First, let’s add the library responsible for routes.

Cargo.toml

{{< highlight toml “linenos=table” >}}

[dependencies] hyper = “0.12” futures = “0.1” pretty_env_logger = “0.3” log = “0.4” reset-router = “0.7”

{{< / highlight >}}

Our main.rs should now look like this

{{< highlight rust “linenos=table” >}} use hyper::{Body, Method, Server}; use futures::{Future};

use std::env;

extern crate pretty_env_logger; #[macro_use] extern crate log;

extern crate reset_router;

use reset_router::{Router, Request, Response};

fn index(_req: Request) -> Result<Response, Response> { Ok(Response::new(Body::from(“ok”))) }

fn main() { env::set_var(“RUST_LOG”, “app=debug”); env::set_var(“RUST_BACKTRACE”, “1”); pretty_env_logger::init();

let addr = "0.0.0.0:3000".parse().unwrap();

let router = Router::build()
    .add(Method::GET, r"/$", index)
    .finish()
    .unwrap();

let server = Server::bind(&addr)
    .serve(router)
    .map_err(|e| eprintln!("server error: {}", e));

info!("Listening on http://{}", addr);
hyper::rt::run(server);

}

#[cfg(test)] mod tests { extern crate speculate; extern crate reqwest as request;

use hyper::StatusCode;
use speculate::speculate;    
use std::thread;
use std::sync::Once;

use super::main;

static SETUP: Once = Once::new();    

speculate! {      
    before {
        SETUP.call_once(|| {
            let _main_server = thread::spawn(main);
        });
    }

    describe "main server routes" {
        it "calls the root path and returns 200" {
            let resp = request::get("http://0.0.0.0:3000").unwrap();
            assert!(resp.status().is_success());
        }

        it "calls an inexistent route and returns 404" {
            let resp = request::get("http://0.0.0.0:3000/notfound").unwrap();
            assert!(resp.status().is_client_error());
            assert_eq!(resp.status(), StatusCode::NOT_FOUND);
        }
    }
}

} {{< / highlight >}}


We removed some type aliases and now we have a regex based router, the library also takes care of the 404. The tests that we had are still the same after this refactoring ;)

{{< highlight shell >}}

running 2 tests INFO app > Listening on http://0.0.0.0:3000 test tests::speculate_0::main_server_routes::test_calls_the_root_path_and_returns_200 … ok test tests::speculate_0::main_server_routes::test_calls_an_inexistent_route_and_returns_404 … ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

{{< / highlight >}}



Previous Post
Rust Basics - Memory
Next Post
Rust and Energy Consumption