Logo

dev-resources.site

for different kinds of informations.

REST API with Rust + Warp 1: Introduction

Published at
4/14/2021
Categories
rust
warp
rest
api
Author
rogertorres
Categories
4 categories in total
rust
open
warp
open
rest
open
api
open
Author
11 person written this
rogertorres
open
REST API with Rust + Warp 1: Introduction

There are a few good web framework options for Rust: actix, rocket, tide, warp... And they all offer some sort of trade-off; but instead of carefully analyzing these intricate aspects (as Luca did here), you simply decided to go with the one that has an explicit reference to Start Trek, right? Not ideal, mafriend, not ideal... Will I blame you? No. You will get nothing but support from me.

And since you're already down this path, I think it might be a good idea for me to show you how I used warp myself to create a REST API (for learning purposes, just like a holodeck battle).

Please note that this is not a tutorial; this is me sharing a process in the hopes that it can help you. Imagine you ask a friend to help you build something. This friend can either point you to the guides she someday used or show you how she actually went about it, not only sharing the code but explaining the whys and hows. This text is a simulation of the latter. In other words, if examples like these are enough to get you going, considering using them instead of reading this somewhat long text (unless you are easily amused by Star Trek references and puns, then stay).

Still up for the ride? Great! Grab your Earl Gray tea (hot!) and let's make it so!


Getting started

First, the playground.

$ cargo new --lib holodeck
Enter fullscreen mode Exit fullscreen mode

Now, there are (at least) two ways to go about it. The first is to serve the API and test it via curl, as Bastian did here; and for this, I would use a binary crate. The other way is to use warp's built-in test functionalities, for which I think it is best to get a library. As one of my main goals was to actually try warp's test module, I chose the second path.

I started by editing the Cargo.toml file and adding two dependencies.

[dependencies]
tokio = { version = "1", features = ["full"] }
warp = "0.3"
Enter fullscreen mode Exit fullscreen mode

Then I wrote a very simple test case. I chose to test a dull GET method. By dull I mean that it will not actually return any data, it will only [1] assume that there will be a mod called filters where the filters will be added (filters are the dorsal spine of warp usage, as shown here); [2]; use the request to make make a GET on the path /holodeck using the assumed filters; [3] and finally compare the answer with the enum StatusCode::ACCEPTED. And because the whole thing is going to be asynchronous, the #[tokio::test] is needed.

#[cfg(test)]
mod tests {
    use warp::http::StatusCode;
    use warp::test::request;
    use super::filters;

    #[tokio::test]
    async fn try_list() {
        let api = filters::list();

        let response = request()
            .method("GET")
            .path("/holodeck")
            .reply(&api)
            .await;

        assert_eq!(response.status(), StatusCode::ACCEPTED);
    }
}
Enter fullscreen mode Exit fullscreen mode

You will notice that I chose not to write use super::filters::* with the *, which would allow me to write things like list() instead of filters::list(); I did so because it makes it easier for me (and for you) to know what is coming from where.

Then, I created the missing filter, which is designed to expect nothing but an empty GET and handle it over to what I call a "Matthew McConaughey handler", because all it has to do is to say alright, alright, alright (a.k.a. StatusCode::ACCEPTED).

mod filters{
    use warp::Filter;
    use super::handlers;

    pub fn list() ->  impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone{ 
        warp::path!("holodeck")
            .and(warp::get())
            .and_then(handlers::handle_list)
    }
}

mod handlers{
    use warp::http::StatusCode;
    use std::convert::Infallible;

    pub async fn handle_list() -> Result<impl warp::Reply, Infallible> {
        // "Alright, alright, alright", Matthew said.
        Ok(StatusCode::ACCEPTED)
    }
}
Enter fullscreen mode Exit fullscreen mode

Why Infallible in the handler's Result? Because if something goes wrong (that's not coded yet), the problem will also be sent as Ok (e.g. Ok(StatusCode::BAD_GATEWAY)).

It might seem like a lot of wasted time, but let me tell you the benefits of doing this (and I'm not even going to get fancy with TDD). For starters, sometimes (maybe every time) it is easier to know what we wanna do than how we're supposed to do it, and tests are a good way to force you to answer this "what" before jumping into the myriad of possible answers to the "how" question. Besides that, these baby steps allowed me to have a clear picture of which function was responsible for which task, who got to be async and who didn't, and so on.

$ cargo test

running 1 test
test tests::try_list ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Enter fullscreen mode Exit fullscreen mode

It worked; not much happened but worked nonetheless.


In the next episode of Engaging Warp...

The next step is to build the POST method. That will require proper coding of both filters and handlers, as well as deserializing the JSON and storing it somewhere.

Anyway, that's all for now. If I said something wrong or made things more complicated than they should be, let me know in the comments.

🖖

warp Article's
29 articles in total
Favicon
Warp AI Terminal: A Beginner’s Guide to the Future of Command Line Interfaces
Favicon
OSX Sequoia & Operation not permitted (os error 1)
Favicon
iTerm on steroids: Why I've Switched to Warp
Favicon
warp adoption guide: Overview, examples, and alternatives
Favicon
Warp terminal on WSL is AMAZING
Favicon
How to use Cloudflare Warp as a socks proxy on your local computer
Favicon
Dank Owl - custom themes in Warp terminal and neovim
Favicon
Reasons to change the default terminal to Warp
Favicon
How Warp Works
Favicon
The terminal is on life support. Is it worth saving?
Favicon
How we designed themes for the terminal - a peek into our process
Favicon
Warp’s product principles for reinventing the terminal
Favicon
How to hire engineers at an early stage startup
Favicon
Code-first vs. Product-first
Favicon
The Biggest Mistake I See Engineers Make
Favicon
Multiply by 𝝅
Favicon
Coding
Favicon
Planning
Favicon
Host Interns
Favicon
ทำไมเรายังไม่ Warp (terminal)
Favicon
Rust Warp: Use Cookie for Authorization
Favicon
REST API with Rust + Warp 1: Introduction
Favicon
REST API with Rust + Warp 3: GET
Favicon
REST API with Rust + Warp 2: POST
Favicon
REST API with Rust + Warp 4: PUT & DELETE
Favicon
REST API with Rust + Warp 5: Beyond test utilities
Favicon
Validating JSON input in Rust web services
Favicon
Dotnet Warp to further optimize .Net self-contained single executable file.
Favicon
My First Rust Web Service (And Other Firsts)

Featured ones: