30天拿下Rust之实战Web Server

概述

        随着互联网技术的飞速发展,Web服务器作为承载网站与应用的核心组件,其性能、稳定性和安全性都显得至关重要。Rust语言凭借其独特的内存安全保证、高效的性能以及丰富的生态系统,成为了构建现代Web服务器的理想选择。

新建项目

        首先,使用下面的命令创建一个新的Cargo项目web_server。

cargo new web_server

        然后,修改Cargo.toml文件,添加必要的依赖项actix-web。actix-web是一个用Rust语言编写的高性能、高度可扩展的Web框架,专为构建安全、快速且资源效率高的Web应用程序而设计。作为Rust生态系统中较早出现且持续发展的项目,Actix-web享有良好的生态环境与活跃的社区支持,使其成为众多Rust Web开发者首选的框架之一。

[dependencies]
actix-web = { version = "4.5.0"}

基础Web服务器

        接下来,我们创建一个最基础的Web服务器,它能够响应HTTP请求并返回简单的字符串响应。

        在下面的示例代码中,我们首先导入了actix_web中的App和HttpServer,它们分别用于构建应用程序和启动HTTP服务器。我们还导入了HttpResponse,用于构建HTTP响应。

        然后,我们定义一个处理HTTP请求的函数index(),这个函数简单地返回一个包含“Hello Rust”文本的HTTP 200 OK响应。

        接下来,在main函数中,我们使用HttpServer::new来创建一个新的HTTP服务器。我们传递一个闭包给new方法,该闭包返回一个App实例。在App实例上,我们使用route方法来定义路由。这里我们定义了一个根路由/,并使用actix_web::web::get()来指定这是一个GET请求。然后,我们将index函数与这个路由关联起来。

        最后,我们使用bind()方法来指定服务器要监听的地址和端口(这里是127.0.0.1:8080),并调用run方法来启动服务器。

use actix_web::HttpResponse;
use actix_web::{App, HttpServer};

async fn index() -> HttpResponse {
    HttpResponse::Ok().body("Hello Rust")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().route("/", actix_web::web::get().to(index)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

        在命令行中运行cargo run来启动程序,此时服务器开始监听localhost:8080。现在,我们可以使用任何Web浏览器来测试服务器。在浏览器中打开http://localhost:8080或者http://127.0.0.1:8080,我们应该能看到服务器返回的“Hello Rust”响应。

处理路由

        为了构建更复杂的Web应用,我们需要引入路由机制。

        在下面的示例代码中,我们添加了一个新的路由/new_route,它映射到一个新的处理函数new_route_handler。这个处理函数简单地返回一个包含文本"New route handler"的HTTP 200 OK响应。现在,服务器将能够响应两个路由:根路径/和新的路径/new_route。

use actix_web::HttpResponse;
use actix_web::{App, HttpServer};

async fn index() -> HttpResponse {
    HttpResponse::Ok().body("Hello Rust")
}

async fn new_route_handler() -> HttpResponse {
    HttpResponse::Ok().body("New route handler")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().
        route("/", actix_web::web::get().to(index))
        .route("/new_route", actix_web::web::get().to(new_route_handler)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

处理JSON请求

        对于API服务,经常需要处理JSON格式的请求与响应。修改Cargo.toml文件,引入serde和serde_json来简化工作。

[dependencies]
actix-web = { version = "4.5.0"}
serde = { version = "1", features = ["derive"] }
serde_json = "1"

        在下面的示例代码中,我们首先导入了serde库中的Deserialize和Serialize特质,它们用于定义结构体可以被自动序列化和反序列化为JSON格式。

        然后,定义了一个名为FormData的结构体,它有一个字段field_name,类型为String。通过derive属性,该结构体获得了从JSON字符串自动反序列化(Deserialize)的能力,以及将自身序列化为JSON字符串(Serialize)的能力,Debug特征使得结构体可以方便地输出调试信息。我们还定义了一个名为JsonResponse的结构体,它有一个字段message,类型也为String。这里只应用了Serialize特质,因为这个结构体是用来构造返回给客户端的JSON响应报文的,不需要反序列化能力。

        最后,我们定义了处理POST请求的异步函数handle_post,它接受一个类型为web::Json<FormData>的参数。web::Json是一个wrapper类型,表示请求体应该被解析为FormData结构体。函数内部首先打印接收到的POST数据,然后创建一个JsonResponse实例,其中message字段内容为"Hello from Rust Server"。函数的最后,返回一个201 Created状态码的响应,主体内容为序列化后的JsonResponse实例。

use actix_web::{web, App, HttpResponse, HttpServer, Result};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug)]
struct FormData {
    field_name: String,
}

#[derive(Serialize)]
struct JsonResponse {
    message: String,
}

async fn index() -> HttpResponse {
    HttpResponse::Ok().body("Hello Rust")
}

async fn new_route_handler() -> HttpResponse {
    HttpResponse::Ok().body("New route handler")
}

async fn handle_post(form_data: web::Json<FormData>) -> Result<HttpResponse> {
    println!("Received POST data: {:?}", form_data.into_inner());
    let response_data = JsonResponse {
        message: format!("Hello from {}", "Rust Server".to_string()),
    };
    Ok(HttpResponse::Created().json(response_data))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index))
            .route("/new_route", web::get().to(new_route_handler))
            .route("/post_data", web::post().to(handle_post))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

        在命令行中运行cargo run来启动程序,此时服务器开始监听localhost:8080。我们可以使用Postman来模拟浏览器发送POST请求的行为,方法选择POST,路径为localhost:8080/post_data,Body选择raw/JSON,输入:{"field_name": "Hello from client"}。点击Send按钮,我们会收到Rust Web Server返回的POST响应,Body为:{"message": "Hello from Rust Server"}。

处理动态路由参数

        要实现动态路由参数,我们可以使用actix-web提供的路径参数功能。路径参数允许我们在URL路径中定义占位符,这些占位符在请求到来时会被解析为具体的值。

        在下面的示例代码中,我们新增了一个异步函数handle_dynamic_route,它接受一个类型为web::Path<String>的参数。web::Path<T>是actix-web提供的一个类型,用于捕获路径参数。这里我们使用String类型来捕获动态路由中的ID。接着,在应用程序配置中,我们添加了一个新的路由。这里的/{id}路径模板中,{id}是一个占位符,表示任何非斜杠字符组成的字符串。当一个请求到达,其URL路径匹配/{id}模板时,actix-web会将路径中对应的值作为web::Path<String>传递给handle_dynamic_route函数。

use actix_web::{web, App, HttpResponse, HttpServer, Result};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug)]
struct FormData {
    field_name: String,
}

#[derive(Serialize)]
struct JsonResponse {
    message: String,
}

async fn index() -> HttpResponse {
    HttpResponse::Ok().body("Hello Rust")
}

async fn new_route_handler() -> HttpResponse {
    HttpResponse::Ok().body("New route handler")
}

async fn handle_post(form_data: web::Json<FormData>) -> Result<HttpResponse> {
    println!("Received POST data: {:?}", form_data.into_inner());
    let response_data = JsonResponse {
        message: format!("Hello from {}", "Rust Server".to_string()),
    };
    Ok(HttpResponse::Created().json(response_data))
}

async fn handle_dynamic_route(id: web::Path<String>) -> HttpResponse {
    HttpResponse::Ok().body(format!(
        "Process dynamic route with ID: {}",
        id.into_inner()
    ))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index))
            .route("/new_route", web::get().to(new_route_handler))
            .route("/post_data", web::post().to(handle_post))
            .route("/{id}", web::get().to(handle_dynamic_route))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

        我们仍使用Postman来模拟浏览器的动态路由参数,方法选择GET,路径为localhost:8080/666,Body选择none。点击Send按钮,我们会收到Rust Web Server返回的GET响应,Body为:Process dynamic route with ID: 666。

总结

        在本文中,我们不仅搭建了一个基础的Web服务器,还实现了路由、JSON请求、动态路由参数等功能。Rust凭借其严谨的安全模型、出色的性能和丰富的生态系统,为构建高效、安全的Web服务器提供了坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/525407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SVG图标显示

SVG图标显示 1.安装SharpVectors.Wpf包 2.添加引用 xmlns:svgc"http://sharpvectors.codeplex.com/svgc/"3.加载svg文件&#xff0c;生成操作选择资源(Resource) 4.UI界面显示SVG图像 <Button Click"OnSaveFileClick" ToolTip"Save Svg File…

4核8G服务器性能怎么样?4核8G12M配置可应对哪些场景?

腾讯云4核8G服务器多少钱&#xff1f;腾讯云4核8G轻量应用服务器12M带宽租用价格646元15个月&#xff0c;活动页面 txybk.com/go/txy 活动链接打开如下图所示&#xff1a; 腾讯云4核8G服务器优惠价格 这台4核8G服务器是轻量应用服务器&#xff0c;详细配置为&#xff1a;轻量4核…

护眼台灯3a好还是2a好?品质护眼灯十大品牌推荐

在如今电子产品普及、学习工作压力增大的背景下&#xff0c;用眼健康问题逐渐受到广大消费者的高度关注。护眼台灯作为改善视觉环境、减轻眼部疲劳的重要工具&#xff0c;其选择显得尤为关键。而在选择护眼台灯时&#xff0c;我们经常会遇到关于3A和2A的疑问&#xff0c;护眼台…

论文| Convolutional Neural Network-based Place Recognition - 2014

2014-Convolutional Neural Network-based Place Recognition

景区云旅游/视频慢直播方案设计与平台搭建

一、行业背景 经文化和旅游部数据中心测算&#xff0c;今年清明节假期3天全国国内旅游出游1.19亿人次&#xff0c;按可比口径较2019年同期增长11.5%&#xff1b;国内游客出游花费539.5亿元&#xff0c;较2019年同期增长12.7%。踏青赏花和户外徒步成为假期的热门出游主题。随着…

k8s单节点部署,容器运行时使用containerd

环境 系统 &#xff1a; entOS Linux release 7.9.2009 (CoreIP&#xff1a;192.168.44.177 硬件要求&#xff1a;控制平面最少需要 2c2g 安装前环境准备 如果是集群部署还需要配置时间同步 关闭防火墙 systemctl disable firewalld关闭selinux setenforce 0sed -i s/SELI…

STC8H8K64U 库函数学习笔记 —— GPIO 点灯

STC8H8K64U 库函数学习笔记 —— GPIO 点灯 环境说明&#xff1a; 芯片&#xff1a;STC8H8K64U 软件&#xff1a; KeilC51 μVersion V5.38.00STCAI-ISP (V6.94) 不得不说&#xff0c;Keil 是我用过的 IDE 中&#xff0c;最让人头疼的事情&#xff0c;写代码就像是在记事本里编…

使用docker-compose创建多项目容器运行

使用docker-compose创建多项目容器运行 按招网友提供方法创建 docker-compose.yml内容&#xff08;这里改了桥接模式&#xff0c;并且注释放开&#xff09; version: "3" services:docker_python:image: python:2.7.18container_name: py_appworking_dir: "/r…

Java实现一个简易的布隆过滤器Bloom Filter

目录 什么是布隆过滤器&#xff1f; 作用&#xff1a; 实现一个简单的布隆过滤器&#xff1a; 解析&#xff1a; 什么是布隆过滤器&#xff1f; 布隆过滤器&#xff08;Bloom Filter&#xff09;是一种用于快速检查一个元素是否可能存在于一个集合中的数据结构&#xff0c;它…

智能化办公时代来临:AI助你解放双手

文章目录 一、AI在办公领域的广泛应用二、AI助力办公效率提升1.自动化流程减少繁琐任务2.智能分析辅助决策制定3.个性化服务提升用户体验 三、AI提升办公效率的未来趋势1.更加智能化的办公场景2.更高效的团队协作3.更全面的数据安全保护 四、应对AI带来的挑战《AI高效工作一本通…

RabbitMQ3.13.x之九_Docker中安装RabbitMQ

RabbitMQ3.13.x之_Docker中安装RabbitMQ 文章目录 RabbitMQ3.13.x之_Docker中安装RabbitMQ1. 官网2. 安装1 .拉取镜像2. 运行容器 3. 访问 1. 官网 rabbitmq - Official Image | Docker Hub 2. 安装 1 .拉取镜像 docker pull rabbitmq:3.13.0-management2. 运行容器 # lates…

顺序统计量

一、顺序统计量 定义&#xff1a;将长度为 n 的数组按升序排序后&#xff0c;第 i 个位置的数字是该数组的第 i 小的量&#xff0c;称之为第 i 顺序统计量。 则一个数组中的最小值是第1顺序统计量&#xff0c;最大值是第n顺序统计量&#xff0c;中位数是第 (n1)/2 顺序统计量 …

图像识别网络与训练策略——基于经典网络架构训练图像分类模型

基于经典网络架构训练图像分类模型 总体框架 数据预处理部分&#xff1a;- 数据增强&#xff1a;torchvision中transforms模块自带功能&#xff0c;比较实用 - 数据预处理&#xff1a;torchvision中transforms也帮我们实现好了&#xff0c;直接调用即可 - DataLoader模块直接…

@四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!

四年级家长&#xff0c;这条香港优才计划华侨生联考捷径&#xff0c;一定要看&#xff01; 香港身份的优势有多大&#xff1f;进可参加华侨生联考400分上内地985/211大学&#xff0c;退可参加香港DSE轻松上香港本地大学和海外高校。 但香港身份对子女的教育优势大小&#xff0c…

C++从入门到精通——this指针

this指针 前言一、this指针的引出问题 二、this指针的特性三、例题什么时候会出现编译报错什么时候会出现运行崩溃this指针存在哪里this指针可以为空吗 四、C语言和C实现Stack的对比C语言实现C实现 前言 this指针是一个特殊的指针&#xff0c;在C类的成员函数中使用。它指向调…

PPT 操作

版式 PPT中&#xff0c;巧妙使用母版&#xff0c;可以提高效率。 双击母版&#xff0c;选择其中一个版式&#xff0c;插入装饰符号。 然后选择关闭。 这个时候&#xff0c;在该版式下的所有页面&#xff0c;就会出现新加入的符号。不在该版式下的页面&#xff0c;不会出现新加…

【Redis】Redis的使用

登录redis [roottest2 ~]# redis-cli 127.0.0.1:6379> 或[roottest2 ~]# redis-cli -h 192.168.67.12 -p 6379 192.168.67.12:6379> redis-benchmark 测试工具 redis-benchmark 是官方自带的Redis性能测试工具&#xff0c;可以有效的测试Redis服务的性能 基本的测试语…

2.类与对象(上篇)

1.面向过程和面向对象初步认识 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完成。 2.类的引入 C**语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定…

(三)LTspice学习交流分析

文章目录 前言一、Edit simulation cmd二、添加激励总结 前言 上一节我们学习了LTspice的安装&#xff0c;很简单&#xff0c;无脑安装 &#xff08;一&#xff09;LTspice简介 &#xff08;二&#xff09;LTspice学习之简介2 今天我们来学习一下LTspice另一个非常重要的仿真功…

血泪教训!程序员副业接单做私活避坑指南!!!

缘起 经常有粉丝朋友向我哭诉留言&#xff0c;告知大白自己兼职被骗的经历&#xff1a; 在大家找兼职踩坑过程中&#xff0c;我总结下来就是以下几点血泪教训&#xff1a; 1. 有没有靠谱兼职推荐&#xff1f; 2. 零基础怎么兼职接单&#xff1f; 3. 怎么渗透&#xff1f;怎么…