位置: IT常识 - 正文

【一起学Rust | 框架篇 | Viz框架】轻量级 Web 框架——Viz(rust 入门教程)

编辑:rootadmin
【一起学Rust | 框架篇 | Viz框架】轻量级 Web 框架——Viz

推荐整理分享【一起学Rust | 框架篇 | Viz框架】轻量级 Web 框架——Viz(rust 入门教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:rust一起玩的yy,rust+app,rust怎么一起玩,快速入门rust,rust 入门教程,rust一起玩的yy,rust tutorial,rust tutorial,内容如对您有帮助,希望把文章链接给更多的朋友!

文章目录前言特点一、Hello Viz1. 创建项目2. 引入viz3. 运行Hello Viz4. 运行结果注意二、Hello Viz代码详解导入组件处理请求主函数三、常见用法简单的处理程序实现处理程序特质路由传参链式组合程序中间件参数接收器路由一个简单的路由CRUD操作资源总结前言

Viz,是个基于RUst的,快速、健壮、灵活、轻量级的 Web 框架。

特点安全,禁止不安全代码轻量简单 + 灵活的处理器和中间件链式操作强大的Routing路由一、Hello Viz1. 创建项目

正如学习编程语言一样,我们先从官方入门案例学起,首先我们创建一个新项目

cargo new viz_hello

然后使用vscode打开

2. 引入viz

在Cargo.toml中写入,如下图

tokio = { version = "1.20.1", features = ["full"] }viz = "0.3.1"

然后使用build来下载依赖

cargo build

安装完成

3. 运行Hello Viz

复制以下代码到main.rs,

use std::net::SocketAddr;use viz::{Request, Result, Router, Server, ServiceMaker};async fn index(_: Request) -> Result<&'static str> { Ok("Hello Viz")}#[tokio::main]async fn main() -> Result<()> { let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); println!("listening on {}", addr); let app = Router::new().get("/", index); if let Err(err) = Server::bind(&addr) .serve(ServiceMaker::from(app)) .await { println!("{}", err); } Ok(())}4. 运行结果

如果你以上步骤没有出错,那么在终端中运行

cargo run

效果如下图 最后一行的意思是正在监听本地的127.0.0.1的3000端口,说明程序没有出错

此时在浏览器打开网址

http://localhost:3000/注意【一起学Rust | 框架篇 | Viz框架】轻量级 Web 框架——Viz(rust 入门教程)

localhost指向127.0.0.1

此时页面应该是这个样子的

二、Hello Viz代码详解

从整体上来看,这块代码主要分为3个部分,分别是导入组件,处理index请求和主程序

导入组件

首先导入了SocketAddr,用来表示socket地址,然后导入了Viz的一些组件

Request 请求Result 响应Router 路由Server 服务器ServiceMaker 服务

处理请求

这里使用异步函数来实现index的处理,传入Request,这个过程系统会自动为我们处理。然后响应的是字符串类型,在函数体中返回了字符串“Hello Viz”

主函数

在Viz中,主函数也是异步函数,使用addr表示本地地址和监听的端口,然后挂载Router,使与index处理器相联系,再开启服务器。

三、常见用法简单的处理程序async fn index(_: Request) -> Result<Response> { Ok(Response::text("Hello, World!"))}async fn about(_: Request) -> Result<&'static str> { Ok("About Me!")}async fn not_found(_: Request) -> Result<impl IntoResponse> { Ok("Not Found!")}实现处理程序特质#[derive(Clone)]struct MyHandler { code: Arc<AtomicUsize>,}#[async_trait]impl Handler<Request> for MyHandler { type Output = Result<Response>; async fn call(&self, req: Request) -> Self::Output { let path = req.path().clone(); let method = req.method().clone(); let code = self.code.fetch_add(1, Ordering::SeqCst); Ok(format!("code = {}, method = {}, path = {}", code, method, path).into_response()) }}路由传参

Viz 允许更灵活地组织代码。

async fn show_user(mut req: Request) -> Result<Response> { let Params(id) = req.extract::<Params<u64>>().await?; Ok(format!("post {}", id).into_response())}async fn show_user_ext(Params(id): Params<u64>) -> Result<impl IntoResponse> { Ok(format!("Hi, NO.{}", id))}async fn show_user_wrap(req: Request) -> Result<impl IntoResponse> { // https://github.com/rust-lang/rust/issues/48919 // show_user_ext.call(req).await FnExt::call(&show_user_ext, req).await}let app = Router::new() .get("/users/:id", show_user) .get("/users_wrap/:id", show_user_wrap) .get("/users_ext/:id", show_user_ext.into_handler());链式组合程序

HandlerExt是Handler的拓展特质,它提供了各种方便的组合函数。比如FutureExt和StreamExt特质。

async fn index(_: Request) -> Result<Response> { Ok(Response::text("hyper"))}async fn before(req: Request) -> Result<Request> { if req.method() == Method::POST { Ok(req) } else { Err(StatusCode::METHOD_NOT_ALLOWED.into_error()) }}async fn around<H>((req, handler): Next<Request, H>) -> Result<Response>where H: Handler<Request, Output = Result<Response>> + Clone,{ // before ... let result = handler.call(req).await; // after ... result}async fn after(result: Result<Response>) -> Result<Response> { result.map(|mut res| { *res.status_mut() = StatusCode::NO_CONTENT; res })}let routing = Router::new() .get("/", index.before(before).around(around).after(after));中间件

Viz 的中间件和处理程序具有共同的Handler特质,因此它很容易实现和扩展中间件。

我们可以将中间件添加到单个处理程序或所有处理程序。

我们还可以在构造过程中使用Transform特质 trait 来包装内部处理程序。

async fn index(_: Request) -> Result<Response> { Ok(StatusCode::OK.into_response())}async fn not_found(_: Request) -> Result<impl IntoResponse> { Ok(StatusCode::OK)}async fn show_user(Params(id): Params<u64>) -> Result<impl IntoResponse> { Ok(format!("post {}", id))}// middleware fnasync fn around<H>((req, handler): Next<Request, H>) -> Result<Response>where H: Handler<Request, Output = Result<Response>>,{ // before ... let result = handler.call(req).await; // after ... result}// middleware struct#[derive(Clone)]struct MyMiddleware {}#[async_trait]impl<H> Handler<Next<Request, H>> for MyMiddlewarewhere H: Handler<Request>,{ type Output = H::Output; async fn call(&self, (i, h): Next<Request, H>) -> Self::Output { h.call(i).await }}// A configuration for Timeout Middlewarestruct Timeout { delay: Duration,}impl Timeout { pub fn new(secs: u64) -> Self { Self { delay: Duration::from_secs(secs) } }}impl<H: Clone> Transform<H> for Timeout { type Output = TimeoutMiddleware<H>; fn transform(&self, h: H) -> Self::Output { TimeoutMiddleware(h, self.delay) }}// Timeout Middleware#[derive(Clone)]struct TimeoutMiddleware<H>(H, Duration);#[async_trait]impl<H> Handler<Request> for TimeoutMiddleware<H>where H: Handler<Request> + Clone,{ type Output = H::Output; async fn call(&self, req: Request) -> Self::Output { self.0.call(req).await }}let app = Router::new() .get("/", index // handler level .around(around) .around(MyMiddleware {}) .with(Timeout::new(1)) ) .route("/users/:id", get( show_user .into_handler() .map_into_response() // handler level .around(around) .with(Timeout::new(0)) ) .post( (|_| async { Ok(Response::text("update")) }) // handler level .around(around) .with(Timeout::new(0)) ) // route level .with_handler(MyMiddleware {}) .with(Timeout::new(2)) ) .get("/*", not_found .map_into_response() // handler level .around(around) .around(MyMiddleware {}) ) // router level .with_handler(around) .with_handler(MyMiddleware {}) .with(Timeout::new(4));参数接收器

从Request中提取参数。

struct Counter(u16);#[async_trait]impl FromRequest for Counter { type Error = Infallible; async fn extract(req: &mut Request) -> Result<Self, Self::Error> { let c = get_query_param(req.query_string()); Ok(Counter(c)) }}fn get_query_param(query: Option<&str>) -> u16 { let query = query.unwrap_or(""); let q = if let Some(pos) = query.find('q') { query.split_at(pos + 2).1.parse().unwrap_or(1) } else { 1 }; cmp::min(500, cmp::max(1, q))}路由

识别URL和分配处理器。

一个简单的路由async fn index(_: Request) -> Result<Response> { Ok(().into_response())}let root = Router::new() .get("/", index) .route("/about", get(|_| async { Ok("about") }));let search = Router::new() .route("/", Route::new().get(|_| async { Ok("search") }));CRUD操作

添加带请求方式的方法。

async fn index_todos(_: Request) -> Result<impl IntoResponse> { Ok(())}async fn create_todo(_: Request) -> Result<&'static str> { Ok("created")}async fn new_todo(_: Request) -> Result<Response> { Ok(Response::html(r#" <form method="post" action="/"> <input name="todo" /> <button type="submit">Create</button> </form> "#))}async fn show_todo(mut req: Request) -> Result<Response> { let Params(id): Params<u64> = req.extract().await?; Ok(Response::text(format!("todo's id is {}", id)))}async fn update_todo(_: Request) -> Result<()> { Ok(())}async fn destroy_todo(_: Request) -> Result<()> { Ok(())}async fn edit_todo(_: Request) -> Result<()> { Ok(())}let todos = Router::new() .route("/", get(index_todos).post(create_todo)) .post("/new", new_todo) .route("/:id", get(show_todo).patch(update_todo).delete(destroy_todo)) .get("/:id/edit", edit_todo);资源// GET `/search`async fn search_users(_: Request) -> Result<Response> { Ok(Response::json::<Vec<u64>>(vec![])?)}// GET `/`async fn index_users(_: Request) -> Result<Response> { Ok(Response::json::<Vec<u64>>(vec![])?)}// GET `/new`async fn new_user(_: Request) -> Result<&'static str> { Ok("User Form")}// POST `/`async fn create_user(_: Request) -> Result<&'static str> { Ok("Created User")}// GET `/user_id`async fn show_user(_: Request) -> Result<&'static str> { Ok("User ID 007")}// GET `/user_id/edit`async fn edit_user(_: Request) -> Result<&'static str> { Ok("Edit User Form")}// PUT `/user_id`async fn update_user(_: Request) -> Result<&'static str> { Ok("Updated User")}// DELETE `/user_id`async fn delete_user(_: Request) -> Result<&'static str> { Ok("Deleted User")}let users = Resources::default() .named("user") .route("/search", get(search_users)) .index(index_users) .new(new_user) .create(create_user) .show(show_user) .edit(edit_user) .update(update_user) .destroy(delete_user);总结

本期主要是对Rust的轻量级Web框架Viz进行了入门级的了解,并且给出了Viz官方的示例代码,包括中间件,响应处理,路由等组件的用法,可以看出Viz是个纯web框架,非常的简洁。在后续的文章中,将会陆续为大家介绍rust的数据库操作,json操作等相关技术,rust做web后端的相关技术补齐就开始项目实战。如果你对rust感兴趣,请关注本系列文章。

本文链接地址:https://www.jiuchutong.com/zhishi/300621.html 转载请保留说明!

上一篇:js-cookie的使用(js-cookie vue)

下一篇:YOLOv5|YOLOv7|YOLOv8改各种IoU损失函数:YOLOv8涨点Trick,改进添加SIoU损失函数、EIoU损失函数、GIoU损失函数、α-IoU损失函数

  • 简谈如何做好电商客户关系管理(如何做好电脑)

    简谈如何做好电商客户关系管理(如何做好电脑)

  • 力源泉净水器滤芯安装顺序图(力源泉净水器)(力泉净水机)

    力源泉净水器滤芯安装顺序图(力源泉净水器)(力泉净水机)

  • 红魔6spro是屏下指纹吗(红魔6p的屏幕)

    红魔6spro是屏下指纹吗(红魔6p的屏幕)

  • 快手闪电购怎么开通(快手闪电购怎么关闭)

    快手闪电购怎么开通(快手闪电购怎么关闭)

  • 微信怎么变回白色主题(微信怎么样变回白色)

    微信怎么变回白色主题(微信怎么样变回白色)

  • 抖音怎么看历史评论(抖音怎么看历史直播回放)

    抖音怎么看历史评论(抖音怎么看历史直播回放)

  • 带着手套如何使用手机(带着手套如何使用苹果手机)

    带着手套如何使用手机(带着手套如何使用苹果手机)

  • 芒果tv骑士卡是什么

    芒果tv骑士卡是什么

  • mate30前置摄像头红点(mate30前置摄像头介绍图)

    mate30前置摄像头红点(mate30前置摄像头介绍图)

  • 抖音点红心对方知道吗(抖音点红心就是喜欢吗)

    抖音点红心对方知道吗(抖音点红心就是喜欢吗)

  • iPhone11没有长焦有什么影响(苹果11没有长焦)

    iPhone11没有长焦有什么影响(苹果11没有长焦)

  • 天猫精灵方糖必须插电用吗(天猫精灵方糖必须插电源才能用吗)

    天猫精灵方糖必须插电用吗(天猫精灵方糖必须插电源才能用吗)

  • 华为畅享9e可以设置返回键吗(华为畅享9e可以应用分身吗)

    华为畅享9e可以设置返回键吗(华为畅享9e可以应用分身吗)

  • win7引用的账户当前已锁定(win7引用的账户已锁定且可能无法登录 没有输错密码)

    win7引用的账户当前已锁定(win7引用的账户已锁定且可能无法登录 没有输错密码)

  • 运算器alu的主要功能是指(运算器alu主要功能是指什么)

    运算器alu的主要功能是指(运算器alu主要功能是指什么)

  • boss直聘注销了还能再注册吗(boss直聘注销了简历还在吗)

    boss直聘注销了还能再注册吗(boss直聘注销了简历还在吗)

  • ps怎么打印照片(ps怎么打印照片6寸照片)

    ps怎么打印照片(ps怎么打印照片6寸照片)

  • 乐视手机怎么导入联系人(乐视手机怎么导出联系人到sim卡)

    乐视手机怎么导入联系人(乐视手机怎么导出联系人到sim卡)

  • 手机给台式电脑开热点(手机给台式电脑供网)

    手机给台式电脑开热点(手机给台式电脑供网)

  • 小米9官方标配有什么(小米官方标配与套餐一的区别)

    小米9官方标配有什么(小米官方标配与套餐一的区别)

  • 潮信怎么删除好友(潮信登陆不了怎么办)

    潮信怎么删除好友(潮信登陆不了怎么办)

  • 华为圆形返回键怎么关(华为圆形返回键设置)

    华为圆形返回键怎么关(华为圆形返回键设置)

  • 京东自营店如何加盟(京东自营店如何运营好)

    京东自营店如何加盟(京东自营店如何运营好)

  • 如何数字权利激活Windows11系统?Win11数字权利激活图文教程(数字权利服务如何打开)

    如何数字权利激活Windows11系统?Win11数字权利激活图文教程(数字权利服务如何打开)

  • 前端技术:解决执行npm install提示 xxx packages are looking for funding run `npm fund` for details的问题 详述npm fund(前端解决方案)

    前端技术:解决执行npm install提示 xxx packages are looking for funding run `npm fund` for details的问题 详述npm fund(前端解决方案)

  • uniapp中单选按钮的实现(uniapp单选功能)

    uniapp中单选按钮的实现(uniapp单选功能)

  • 无需公网IP,远程连接SQL Server数据库【内网穿透】(没有公网ip如何实现外网访问路由器)

    无需公网IP,远程连接SQL Server数据库【内网穿透】(没有公网ip如何实现外网访问路由器)

  • 补提以前年度的盈余公积可以在本年任意月份提取吗
  • 房地产开发企业资质等级有几个
  • 实际出资人享有什么权利
  • 出租固定资产的折旧额是什么意思
  • 小卖部的货源怎样提供的
  • 白酒消费税纳税人
  • 招待客人的住宿费能抵扣吗?
  • 印花税缴款了发现报错了怎么办?
  • 承包费收入如何交增值税
  • 单式记账法是什么意思呀
  • 超额库存现金
  • 变更银行手机号需要去银行吗
  • 一般纳税人企业所得税政策最新2023税率
  • 投资收益在什么科目
  • 工会经费按上年工资总额还是本年
  • 建筑施工企业印花税计税依据
  • 即征即退增值税政策
  • 增值税发票抵扣进项税什么意思
  • 往来科目明细表
  • 去年红字发票怎么做账
  • 金融服务利息税率是多少
  • 应付账款周转天数上升的原因
  • 主营业务收入会计英语
  • 车辆保险抵扣会计分录
  • 如何删除win11的入门
  • 技术开发免征增值税怎么开票
  • 租赁合同维修义务谁承担
  • 普通发票的进项票怎么做分录
  • php解构
  • 购进农产品发生非正常损失
  • 房产税具体内容
  • 购入固定资产如何折旧
  • 审核凭证的操作步骤
  • 税款滞纳金和罚款
  • laravel框架实现增删改查
  • nginx反向代理未知域名
  • 税收滞纳金的最新法律规定
  • 钢琴块小游戏在线玩
  • 块元素和行内元素区别
  • 微信小程序获取地理位置
  • vue计算属性和监听属性的区别
  • 短期借款的会计科目
  • 注册新公司怎么办理
  • python用内置函数来打开文件
  • 什么时候进项税转出
  • mysql查询数据库前五条信息
  • sql优化常用的15种方法
  • 物流进项发票应纳税额
  • 自产和外购用于赠送
  • 小额贷款公司如何做账
  • 待抵扣进项税的限额是什么
  • 资产减值损失应计入什么科目
  • 公司开发新产品的建议
  • 收到发票挂账如何处理
  • 进项3个点销项13个点是需要交10个点的税吗
  • 中级报名规则
  • 旅客运输进项抵扣加计扣除怎么算
  • 以股权入资该怎么办
  • 收到红字发票如何认证呢
  • 经营杠杆系数的经济含义
  • 公司一般户的钱怎么拿出来
  • 主营业务成本和主营业务收入的关系
  • 会计账簿的设计要与会计报表相衔接 ()X
  • mysql5.5改密码
  • 开始菜单里设置在哪里
  • 盘符在哪
  • docker untagged
  • 不会安装系统怎么安装
  • profiler.exe - profiler是什么进程 有什么用
  • qvp32.exe - qvp32是什么进程 有什么作用
  • centos7搭建frp
  • jquery的实现原理
  • 将Bitmap用Base64转码成字符串,再解码回来出现黑色背景的问题原因及解决办法。
  • unity的monodevelop
  • jquery给元素添加属性值
  • javaScript parseInt字符转化为数字函数使用小结
  • duck有鸭肉的意思吗
  • listview报错
  • 全资子公司和全资子企业的区别
  • 湖北税务发票查询系统网
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设