前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >warp框架教程5-Filter系统中各个模块

warp框架教程5-Filter系统中各个模块

作者头像
zy010101
发布2023-07-24 16:41:40
3120
发布2023-07-24 16:41:40
举报
文章被收录于专栏:程序员

any 模块

any 模块只有一个方法,就是 any 方法,它可以匹配任何路由的过滤器。我们可以使用 any 方法将一些可克隆的资源转换成一个过滤器,从而允许轻松地将它与其他 Filter 结合在一起。当然也可以使用 any 方法创建适用于多个 Filter 的末尾调用的 Reply。例如:

代码语言:javascript
复制
use warp::Filter;

let route = warp::any()
    .map(|| {
        "I always return this string!"
    });

这个例子将会匹配任何路由,然后返回 “I always return this string!” 。 文档中的另一个例子是

代码语言:javascript
复制
use std::sync::Arc;
use warp::Filter;

let state = Arc::new(vec![33, 41]);
let with_state = warp::any().map(move || state.clone());

// Now we could `and` with any other filter:

let route = warp::path::param()
    .and(with_state)
    .map(|param_id: u32, db: Arc<Vec<u32>>| {
        db.contains(&param_id)
    });

通过 any,我们将 state 成功转换成为一个 Filter,然后我们就能将 state 和其他 Filter 结合起来使用。

body 模块

body 模块用来提取请求中的 body, 它提供了一些方法,如下所示:

不过,现代的web api通常只使用 json 来进行通信。文件上传,下载之类的可能会交给专门的文件服务系统,因此可能也很少使用 form,stream,bytes,aggregate。如果需要使用,可以自行查看文档。而限制请求体的大小,我们更多可能是通过反向代理服务器来进行限制,而不是使用 content_length_limit。

因此,我们通常需要使用的方法只剩下一个,那就是 json, 使用 json 方法可以提取json 反序列化后的内容,前提是我们需要安装 serde_json 来提供反序列化的能力。在第一篇的时候,我们已经安装了 serde 和 serde_json

compression 模块

在 compression 模块,提供了 brotli,gzip,default 三种压缩方式的方法。如下所示:

压缩功能通常由静态服务器实现。当客户端向服务器请求静态资源(如HTML、CSS、JavaScript文件)时,服务器可以应用压缩算法对这些文件进行压缩,并将压缩后的文件发送给客户端。这样可以减少传输的数据量,加快页面加载速度,并降低带宽消耗。

动态服务器主要负责处理动态内容的生成和响应,例如处理用户提交的表单数据、执行数据库查询等。压缩静态资源一般是在静态服务器层面进行的,因为静态资源在每次请求时都可以使用相同的压缩版本,而动态内容则根据每个请求的不同而生成,无法事先进行压缩。

因此,如果你只在 warp 中实现 web api,那么是无需关心压缩问题的。如果你使用模板渲染,前后端不分离的模式,也是可以进行预处理压缩,然后交给静态服务器代理。因此这个问题主要是由静态服务器解决。如果需要使用 compression,可以参考文档。

cookie 模块

cookie 模块有两个方法,可以用于获取HTTP 请求中的携带的cookie,而不是操作响应中的 cookie。

这两个方法的功能是显而易见的,cookie 方法可以从请求中根据 cookie 名称获取相应的 cookie 值,这个值是必须的,否则将会产生一个 warp::reject::Rejection;而 optional 方法则不要求这个 cookie 是必须的,如果找到,则提取 cookie 的值,否则将继续请求。

cors 模块

cors 模块只有一个方法,就是 cors 方法,使用它可以产生一个 cors 对象,通过该对象,我们可以设置允许的跨域请求方法,允许的跨域来源。

文档中的 demo 如下所示:

代码语言:javascript
复制
use warp::Filter;

let cors = warp::cors()
    .allow_origin("https://hyper.rs")
    .allow_methods(vec!["GET", "POST", "DELETE"]);

let route = warp::any()
    .map(warp::reply)
    .with(cors);

如果你想允许所有请求来源,那么可以这样:

代码语言:javascript
复制
use warp::Filter;
let cors = warp::cors()
    .allow_any_origin();

这是 warp 给我们提供的跨域处理。你可以选择使用它,或者也可以在反向代理服务器(例如:Nginx, Apache)处进行跨域的处理。毕竟解决跨域的方式比较多,实际中常用的可能是在反向代理处处置跨域。

ext 模块

这个模块的作用未知,翻看了一下 warp 的源码,发现了下面的使用方式,但是现在版本的 warp 根本没有这个 set 方法。

代码语言:javascript
复制
#![deny(warnings)]
extern crate warp;

use warp::Filter;

#[derive(Clone, Debug, PartialEq)]
struct Ext1(i32);

#[test]
fn set_and_get() {
    let ext = warp::any()
        .map(|| {
            warp::ext::set(Ext1(55));
        })
        .untuple_one()
        .and(warp::ext::get::<Ext1>());

    let extracted = warp::test::request().filter(&ext).unwrap();

    assert_eq!(extracted, Ext1(55));
}

#[test]
fn get_missing() {
    let ext = warp::ext::get().map(|e: Ext1| e.0.to_string());

    let res = warp::test::request().reply(&ext);

    assert_eq!(res.status(), 500);
    assert_eq!(res.body(), "Missing request extension");
}

#[test]
#[should_panic]
fn set_outside_of_filter_should_panic() {
    warp::ext::set(Ext1(55));
}

从这个例子来看,就是可以设置一个值,然后获取。这就导致该模块实际上没什么用,因为我们可以通过 Filter 的 Extract 来带回一个值,然后传递给 map 或者 and_then 中的方法。因此有没有 ext 模块并不影响我们使用 warp。

fs 模块

该模块用来返回一个 file response,在较小的项目下通常是有用的,因为这个时候我们可能不会使用专门的文件系统来存储文件,而是直接在我们的后端 API 中进行处理。(即使是动态生成文件,例如导出Excel,也应该将生成的文件存储在专门的文件系统中。)另外一点就是通常我们都是由静态服务器来处理静态文件的,而不是由动态服务器处理。

它提供的方法如下所示:

文档中的示例如下所示,都是处理静态文件的。

代码语言:javascript
复制
use warp::Filter;

// Matches requests that start with `/static`,
// and then uses the rest of that path to lookup
// and serve a file from `/www/static`.
let route = warp::path("static")
    .and(warp::fs::dir("/www/static"));

// For example:
// - `GET /static/app.js` would serve the file `/www/static/app.js`
// - `GET /static/css/app.css` would serve the file `/www/static/css/app.css`
代码语言:javascript
复制
// Always serves this file from the file system.
let route = warp::fs::file("/www/static/app.js");
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • any 模块
  • body 模块
  • compression 模块
  • cookie 模块
  • cors 模块
  • ext 模块
  • fs 模块
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档