#web-server #flask #服务器 #http #服务器框架 #请求-响应

猩猩

类似Flask的超级简单、轻量级Rust Web服务器框架

5个版本

0.1.4 2024年7月7日
0.1.3 2024年7月3日
0.1.2 2024年7月3日
0.1.1 2024年7月3日
0.1.0 2024年7月3日

#750 in HTTP服务器

每月21次下载

MIT许可协议

45KB
857

猩猩

猩猩是一个轻量级且超级简单的Rust Web服务器库,灵感来自Python的Flask

安装(cargo)

遗憾的是,由于宏的存在,您必须添加多个crate才能使用猩猩,这将在将来得到修复,但现在是,我很抱歉给您带来不便。

在Cargo.toml中添加

[dependencies]
orangutan = "0.1.0"
lib_shared = "0.1.0"
ctor = "0.2.8"

用法

这是一个最小化猩猩应用程序的示例

use orangutan::*;

// Use the 'route'-macro to define the path, method(s) and a handler
#[route(path="/hello", method="[POST, GET]")] 
fn hello_handler(request: &Request) -> Response {

    // Handler has to return a Response           
    let mut res = Response::new();

    // Use the 'insert'-method to insert text/json into the Response     
    res.insert("Hello!"); 

    res 

}

fn main() {    
    // Create an new Orangutan
    let mut app = Orangutan::new("127.0.0.1:8080"); 

    // This automatically makes the Orangutan run with the handler and routes assigned to it.      
    app.run();

    // Now you have a web server listening on http://127.0.0.1:8080/hello 
    // Simple, right
} 

程序输出

* orangutan being served!
    *  orangutan running on http://127.0.0.1:8080/hello (Press CTRL+C to quit)

我建议使用ngrok等软件将Web服务器公开,因为猩猩没有这样做的方法。

示例

猩猩是一个非常强大且有用的工具。以下是猩猩可以做到的一些事情!

路径中的变量

use orangutan::*;

// Same as defining a normal route but with the path containing the type and variable name.
#[route(path="/<str:username>", method="[GET, POST]")]
fn username_handler(request: &Request) -> Response {
    // This handler is responsible for every request in the path: "/something"
    // The name of the variable (username) is defined after the variables type 

    let mut res = Response::new();          

    // We use the get_var() method to get the value of the variable in the request
    let username: String = request.get_var("username");

    // We can do whatever we want with the username
    res.insert(format!("Hello, {}", username));    

    res

}

// Same thing with the username path but now the value of the variable is i32
#[route(path="/<int:number>", method="[POST, GET]")]
fn number_handler(request: &Request) -> Response {
    // This handler is responsible for every request in the path: "/something"
    // Same as username handler except the value of the variable is i32.  

    let mut res = Response::new();          

    let number: i32 = request.get_var("number");

    res.insert(format!("{} * 2 = {}", number, number*2));    

    res

}

fn main() {    
    let mut app = Orangutan::new("127.0.0.1:8080");   

    app.run();     
}

JSON请求

在这个例子中,我将向您展示如何处理包含JSON数据的请求

use orangutan::*;

#[route(path="/order", method="[GET, POST]")]
fn order_handler(request: &Request) -> Response {

    let mut res = Response::new();          

    // .json() returns an Option<Value>, where Some represents the JSON Value and None means that there is no JSON Value in the request
    let order_data = request.json();

    // Let us use match to see if the request contains JSON Value or not
    match order_data {
        // Great. The reqeust contains JSON Value
        Some(data) => { 
            let order: Option<&Value> = data.get("order");

            println!("The order: {}", order.unwrap());
        }
        None => { println!("This means that the request does not contain any JSON data");}
    }    

    res
}

fn main() {    
    let mut a = Orangutan::new("127.0.0.1:8080");   

    a.run();     
}

在Linux上使用curl等工具测试这是如何工作的一个好方法。让我们看看我们的程序是如何表现的。

curl -i -H "Content-Type: application/json" -X POST -d '{"order":"Computer", "OS": "Linux"}' http://127.0.0.1:8080/order

让我们看看我们的程序如何响应这个

程序的输出

The order: "Computer"

如果请求不包含任何JSON值呢?

让我们使用这个命令

curl -X GET -H "Content-Type: text/plain" -d "This is not Json Value" http://127.0.0.1:8080/order

再次,输出是这个

This means that the request does not contain any JSON data

如果请求包含JSON值,但值中不包含"order"字段,则我们的程序将'panic',但幸运的是,这并没有使服务器崩溃。

中止请求

有时您只需要返回一个错误。就是这样

use orangutan::*;

#[route(path="/only_vip", method="[GET, POST]")]
fn user_satus_handler(request: &Request) -> Response {

    let mut res = Response::new();          

    let user_data = request.json();
    
    match user_data {        
        Some(data) => { 
            let user_status: Option<&Value> = data.get("user_status");

            if user_status.unwrap() != "VIP" {
                // Use the abort method to create an error for Response. Only 403, 404 and 500 are valid errors for now.
                res.abort(request, 403);
            } else {
                res.insert("Welcome to the club!");
            }            
        }

        None => { res.abort(request, 404) }
    }    

    res
}

编写响应

有很多方法可以创建响应。这里有一些不同的方法来做同样的事情。

use orangutan::*;

#[route(path="/", method="[GET, POST]")]
fn handler(request: &Request) -> Response {

    let mut res = Response::new();          

    // Here are 3 methods for doing the same thing
    res.set_content_type(ContentType::TextHtml);
    res.set_status(200);
    res.append("Hello!");

    res.insert("<p>Hello!</p>");

    res.insert("Hello!");
    res.set_content_type(ContentType::TextHtml);

    res
}

贡献

欢迎拉取请求。对于重大更改,请首先提出问题以讨论您想要更改的内容。

许可协议

MIT

依赖项

~7–10MB
~178K SLoC