Crate rastapi

Source
Expand description

§RastAPI

RastAPI is a easy-to-use Rust library for creating low-boilerplate, efficient RESTfull APIs, inspired by FastAPI (Python). You define route handler (functions) and map them with their corresponding url and you have a functioning route. RastAPI follows a Non Blocking IO structure for efficient and conccurent handling of requests. We achieve Non blocking IO by following a Threadpool architecture. We can set the number of threads in the pool before starting the application. RastAPI also has a very efficient LFU-LRU based file caching system.It’s a multi threaded cache system, so we used efficient lock stripping techniques to reduce lock contentions.

§Features

  • Minimal boilerplate for defining routes and handlers.
  • High performance leveraging Rust’s coccurency and safety.
  • Very efficient file uploads and downloads.

§Example

§Text or Json Response

    use rastapi::RastAPI;
    use rastapi::Request::HttpRequest;
    use rastapi::Response::{HttpResponse,create_response};
    use rastapi::utils::ContentType;
    use std::collections::HashMap;
    
    // Define a Function/Route handler.
    // With this exact fucnction signature.
    // i.e. fn function_name(request_obj:&HttpRequest,path_params:HashMap<String,String>)->HttpResponse
    // request_obj is parameter where all the details of the incoming request is stored.
    // path_params is a parameter where url path params are stored. Not confuse it with url query parameters.
    // query params are stored in request_obj.params.

    fn json(request_obj:&HttpRequest,path_params:HashMap<String,String>)->HttpResponse{

        let json_content=r#"{
        "name" : "Rony",
        "batch" : 2024,
        "sem" : 3,
        "subjects" : ["OS","Networking","Algorithms"],
        "grade" : {
        "OS" : "C",
        "Cryptography" : "C",
        "Algorithms" : "C"
                   }           
        }"#;

        let resp=create_response(&json_content, 200,ContentType::JSON,true).unwrap(); //create_response(string_content,HTTP_CODE,
        return resp;                                                                  // ContentType,keep_alive_flag)
    }
    fn main(){
        let mut app=RastAPI::new();
        // Set number of workers. It indicates total number of simultaneous requests it can serve.
        app.set_total_workers(5);
        // Map the function/route handler with corresponding url route.
        app.register_route("/json",vec!["GET"],json);
        app.run("0.0.0.0",5000);
    }

§File response

One of the most powerfull features of rastapi is It’s very efficient file uploads downloads. If a file is Not found on system then the server automatically sends 404 Not Found response.

    use rastapi::RastAPI;
    use rastapi::Request::HttpRequest;
    use rastapi::Response::{HttpResponse,send_file};
    use rastapi::utils::FileType;
    use std::collections::HashMap;

    fn file(req:&HttpRequest,path_params:HashMap<String,String>)->HttpResponse{
    let mut resp=send_file("file_path/file_name.ext",Some("file_name.ext".to_string()),FileType::MP4,200,true).unwrap(); // send_file0(file_path,file_name
    resp.add_header("Header-Name","Header-Value");                                              //  file_type,HTTP_CODE,keep_alive_flag)
    return resp;
    }
    fn main(){
        let mut app=RastAPI::new();
        app.set_total_workers(5);
        app.register_route("/file",vec!["GET"],file);
        app.run("127.0.0.1",5000);
     }

§Load local enviornment variables and access them from std::env module.

    use rastapi::RastAPI;
    use rastapi::Request::HttpRequest;
    use rastapi::Response::{HttpResponse,send_file};
    use rastapi::utils::FileType;
    use rastapi::utils::load_env;
    use std::collections::HashMap;
    use std::env;
    fn file(req:&HttpRequest,path_params:HashMap<String,String>)->HttpResponse{
    let mut resp=send_file("file_path/file_name.ext",Some("file_name.ext".to_string()),FileType::MP4,200,true).unwrap(); // send_file0(file_path,file_name
    resp.add_header("Header-Name","Header-Value");                                              //  file_type,HTTP_CODE,keep_alive_flag)
    return resp;
    }
    fn main(){
        load_env::load_env(); // Loads all local enviornment variables in .env file.
        let mut app=RastAPI::new();
        app.set_total_workers(5);
        app.register_route("/file",vec!["GET"],file);
        let port:u16=env::var("PORT").unwrap().parse().unwrap();
        app.run(env::var("HOST").unwrap().as_str(),port);
     }

§Cache

RastAPI uses a slightly tweaked version of a standard LFU-LRU (LFU for eviction and LRU when there is a tie between frequencies of two entity) cache. It only caches files for now. It’s a multi threaded cache So for syncronization we use locks (Mutex). We cann’t use RwLock as for LRU-LFU cache as every read qyery is a write query. So there is a issue of Lock contention. To mitigate lock contention we devided the cache into multiple parts (CacheStore) and lock them individually, thus reducing load on single cache store. We can set total cache size and total number of cache stores.

    use rastapi::RastAPI;
    fn main(){
    let mut app=RastAPI::new();
    #[cfg(feature="cachung")]
     app.set_cache_config(500,10); // Total cache size is set to 500 MB and
                                   // total number of cache stores set to 10
}

§Persistent Connections

RastAPI supports persistent connections. If you want a route to be persistent then set the keep_alive flag in create_response or send_file as true. You can tweak the keep alive behabiour like maximum number of keep alive requests i.e. total number of request response cycle on a signle connection can be set, default value is 10. You can also set the keep alive timeout, i.e. for how much time we wait for next request after sending a response on persistent connection. If we don’t recieve new request for this duration then we drop the connection. Default value is 5 seconds.

    use rastapi::RastAPI;
    fn main(){
    let mut app=RastAPI::new();
    app.set_keep_alive_time_out(3);
    app.set_maximum_keep_alive_requests(10);
    app.run("127.0.0.1",5000);
}

§Stop the app

To stop the app gracefully you need to send SIGINT (CTRL + C) or SIGTERM. SIGTSTP(CTRL + Z) is ignored.

Modules§

Request
Request
Response
Response
utils
Utils

Macros§

error
log_info
log_response_2xx_content
log_response_2xx_file
log_response_3xx_content
log_response_3xx_file
log_response_4xx
log_response_5xx
log_warning

Structs§

RastAPI
This is the main API struct. Before doing anything we need to initialize it.