loading...

Hyper Webapp Template

Ben Lovy on February 20, 2020

Like many of us, I'm quite lazy. When making a wep application, lots of the core functionality will be the same from codebase to codebase. You ne... [Read Full]
markdown guide
 

Great post, you always seem to post just what I'm looking for, are you reading my mind?, be honest, are you?, are you doing it now?

I'm in the look for an alternative to Actix for a plan B or maybe migrate from it entirely, and so far Tide, Warp and plain Hyper looks like my contenders, did you check Tide out? what made you take Hyper instead of their own Warp?

 

I've not actually used Tide or Warp, but they do both look cool. Honestly, I'm still lurched by breaking API changes and an unstable ecosystem. I stuck with Hyper because it's simple, and while it does still change (recently, to support async/await), it likely won't change much further at this point. All these other tools are built around it, I believe.

I think I need to wait for more complex tools to bake longer before I'm ready to start investing time in things like personal use templates. I want this and the other Hyper templates I produce to kind of be "set it and forget it" to the extent possible, and Tide just ain't it yet.

I also already knew how to use it from before the syntax change. I have no complaints about it, which is reason enough to not tool-hop!

 

Wonderful.
I think to work professional, I have not to use any frameworks for security and also business safe.
I would prefer to build web server using the rust book example rather than using any open source framework.
what is your opinion?
you know what happen with actix then now where is rockets.
how can I assure that the frame wrok does not have any spam.
Do not tell me to check the code because if I go to framework to save time so that will be no sense to study the code

Agreed - though honestly, I wish I COULD use Rocket. It actually looks great, but nightly-only is a complete dealbreaker.

 

Great stuff - but Ben... where are the tests? :D

Actually, I'm not just trolling you. I've been dipping my toes back into Rust for a few days and started trying to write something in Hyper. I tried to do what I would normally do for this sort of thing: write a test for one of the handler functions.

I got to this:

use hyper::{Request, Body, Response, http};

pub async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, http::Error> {
    Response::builder()
        .status(http::StatusCode::OK)
        .body(Body::from("Hello, world"))
}

#[cfg(test)]
mod tests {
    use crate::hello_world;
    use hyper::{Request, Body};
    use tokio::runtime::Runtime;

    #[test]
    fn hello_world_server() {
        let mut runtime = Runtime::new().unwrap();

        let request = Request::new(Body::from(""));
        let future = hello_world(request);
        let response = runtime.block_on(future).unwrap();
        let bytes = runtime.block_on(hyper::body::to_bytes(response)).unwrap();
        let string = String::from_utf8(bytes.to_vec()).unwrap();

        assert_eq!(string, String::from("Hello, world"))
    }
}

Which I'm not crazy about - feels like I'm repeatedly unwinding a future then unwrapping a result. Gets the job done but feels a bit like I'm banging these rocks together. You know anything more elegant?

 

Heh - you nailed it with banging rocks together. I'm still playing with these, I don't know what to do either:

#[cfg(test)]
mod tests {
    use super::*;
    use flate2::read::ZlibDecoder;
    use hyper::body;
    use select::{
        document::Document,
        predicate::{Name, Predicate},
    };
    use tokio::runtime::Runtime;

    #[test]
    fn test_four_oh_four() {
        let mut rt = Runtime::new().unwrap();
        let response = rt.block_on(four_oh_four()).unwrap();
        let bytes = rt.block_on(body::to_bytes(response)).unwrap();
        let mut d = ZlibDecoder::new(&bytes[..]);
        let mut html = String::new();
        d.read_to_string(&mut html).unwrap();
        let document = Document::from(html.as_str());
        let node = document
            .find(Name("main").descendant(Name("h1")))
            .next()
            .unwrap();
        assert_eq!(node.text(), "NOT FOUND!");
    }
}

 

That made me feel better - misery loves company!

I'm planning to include a fuller set with the forthcoming CRUD template, I'll copy the relevant ones back over.

They may not be pretty, but at least they'll be there...

 

As a huge fan of microframeworks with swappable plug-ins I approve of this 🔥🔥🔥

Still gotta learn Rust though 😂

 

Still gotta learn Rust though

Hey, me too!

code of conduct - report abuse