当前位置: 首页 > article >正文

Rust: Web框架Axum和Rest Client协同测试

Axum作为Rust当红Web框架,值得了解一下。下面实例包括几个典型的常场场景。
具体如下:

一、Axum

1、toml中依赖


[dependencies]
tokio = {version="1.39.3",features =["full"]}
axum ={version ="0.7.5",features =["tokio"]}
serde = {version ="1.0.209",features =["derive"]}
serde_json ="1.0.1"

2、main.rs

涉及到简单路由和提取器等,包括主要类型的文件形态的处理。

use axum::{
    routing::{get,post},
    Router,
    response,
    Form,
    http::{header::HeaderMap},
};
use serde_json::{Value, json};
use serde::Deserialize;
use axum::extract::{ Query,Json,Path};
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Deserialize,Debug)]
struct User {
    name: String,
    old: i32,
}

#[derive(Deserialize)]
struct LoginForm {
    account: String,
    password: String,
}
#[derive(Deserialize,Debug)]
struct Params {
    tradedays: Option<i32>,//Option=>字段可以缺省
    price:Option<f64>,
    name: Option<String>,
}
#[derive(Deserialize,Debug)]
struct Strategy {
    name: String,
    amount: f64,
    id: i32,
}
#[derive(Debug)]
struct AppState {
    count: i32
}
#[tokio::main]
async fn main() {
    let shared_state = Arc::new(AppState { count:0 });
    let app = Router::new()
        .route("/", get(hello))
        .route("/headers",get(headers))
        .route("/html", get(hello_html))
        .route("/form", get(show_form).post(accept_form))
        .route("/hashmap", get(query_hashmap))//全部解释成hashmap
        .route("/user/:name/:old", get(query_user)) 
        .route("/path/:name/:id", get(path)) //两个参数
        .route("/json", post(query_user_json))
        .route("/query_json",post(
             {
                let shared_state = Arc::clone(&shared_state);
                move |body| query_json(body,shared_state)
             }   
        ,))
        .route("/params",get(get_params))
        .route("/strategies/", get(query_strategy));
    println!("Serving on http://localhost:8080 ...");
    let listener = tokio::net::TcpListener::bind("127.0.0.1:8080").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn headers(headers: HeaderMap) ->String{
    format!("{:?}", headers)
}
// Query: ?和=来解析
async fn get_params(Query(params): Query<Params>) -> String {
    let tradedays = params.tradedays.unwrap_or(0);
    let price = params.price.unwrap_or(0.0);
    let name = params.name.unwrap_or("no name".to_string());
    format!("tradedays {:?}, price: {:?}  name:{:?}", tradedays, price,name)

}
//多个复杂的参数
async fn query_strategy(Json(strategy): Json<Strategy>) ->String{
    println!("strategy :{:?}",strategy);
    format!("receive=> strategy:{:?}",strategy)
}
//Json(user):Json<User>
async fn query_hashmap(Query(inputs): Query<HashMap<String, String>>) -> String{
    println!("inputs:{:?}",inputs);
    format!("inputs:{:?}",inputs)
}
async fn query_user(Path(user):Path<User>){
    println!("welcome! user:{user:#?}");
}
async fn query_user_json(Json(user): Json<User>) -> response::Json<Value>{
    println!("response:{:?}",user);
    Json(json!({ "user": user.name, "old": user.old }))
}
async fn query_json(Json(user):Json<User>,arc: Arc<AppState>)->String{
    println!("arc:{:?}",arc);
    format!("user:{:?} ",user)
}

// `&'static str` becomes a `200 OK` with `content-type: text/plain; charset=utf-8`
async fn hello() -> &'static str {
    "Hello, World!"
}
async fn path(Path((name,id)):Path<(String,i32)>) ->String{
    println!("hi,{name:#?} => id {id:#?}");
    format!("hi,{},{}",name,id)
    
}
// `Html` will get a `text/html` content-type
async fn hello_html() -> response::Html<&'static str> {
    response::Html("
        <h1>Hello HTML</h1>
        <p>Hello, World!</p>
    ")
}

async fn show_form() -> response::Html<&'static str> {
    response::Html(r#"
        <html>
        <head>
            <title>Login Form</title>
        </head>
        <body>
            <h1>User Info</h1>
            <form method="post">
                <label for="field1">account:</label>
                <input type="text" name="field1" id="field1"><br>

                <label for="field2">password:</label>
                <input type="text" name="field2" id="field2"><br>

                <input type="submit" value="Submit">
            </form>
        </body>
        </html>
    "#)
}

async fn accept_form(Form(login): Form<LoginForm>) -> response::Html<String> {
    let response_html = format!(
        r#"
        <html>
        <head>
            <title>Form Submission Result</title>
        </head>
        <body>
            <h1>Form Submission Result</h1>
            <p>account : {}</p>
            <p>password: {}</p>
        </body>
        </html>
    "#,
        login.account, login.password);
    
    println!("response_html: {}", response_html);
    response::Html(response_html)
}

二、Rest Client工具协同测试

在vscode中下载Rest Client插件后,通过创建以.http 或 .rest为结尾的文件,进行http请求测试。具体Rest Client功能很强大,这里只介绍,与Axum配合测试的方案。

具体如下:


# 头文件和body之间要有空隔行

### 值中不需要引号!
@url = http://localhost:8080 
@name = wowotuo
@token =ad;ipiqedqeqeqeqepqei1213132;dkqdqeqe
@id =6

### =>"/";GET;
GET {{url}}/ HTTP/1.1

### =>"/html";GET
GET {{url}}/html HTTP/1.1
### /headers
GET {{url}}/headers  HTTP/1.1

### /path/:name/:id ; id为输入参数
GET {{url}}/path/{{name}}/{{id}} HTTP/1.1


### =>/form;有GET和POST两部分;POST方法要求输入
POST {{url}}/form HTTP/1.1
Content-Type: application/x-www-form-urlencoded

account={{name}}&password=dbfund



### /json; POST.输入user的json格式; 注意JSON格式要"双引号"!
POST {{url}}/json HTTP/1.1
content-type: application/json; charset=utf-8

{
    "name": "{{name}} 你好!",
    "old": 19

}

### /user/:name/:old; 另外一种表达形式
GET {{url}}/user/{{name}}/32  HTTP/1.1

### /params
GET {{url}}/params?tradedays=3&price=3.9&name=breaking

### /hashmap; POST,要求输入hashmap
GET {{url}}/hashmap?name={{name}}&old="19"  HTTP/1.1


### 对于curl命令的支持 类似 =>GET {{url}}/html
curl --request GET \
     --url {{url}}/html

###--header 'user-agent: vscode-restclient'


三、输出
用Rest Client调试的结果是非常直观。
在这里插入图片描述


http://www.kler.cn/news/289298.html

相关文章:

  • 从 Oracle 到 TiDB 丨数据库资源评估指南
  • CUDA与TensorRT学习一:并行处理与GPU体系架构
  • 名城优企游学活动走进龙腾半导体:CRM助力构建营销服全流程体系
  • nginx部署前段VUE项目
  • wsl2 无法上网解决方法
  • 文本文件完整性判断-加密
  • Python中排序算法之冒泡排序
  • Soul Machines——AI生成虚拟主播或虚拟人,模拟真人交互
  • 后端MVC三层架构,Mybatis ,雪花算法生成唯一id
  • 『功能项目』销毁怪物蛋的Shaders消融特效【17】
  • SpringDataJPA系列(5)@Query应该怎么用?
  • QT connect的使用
  • 算法练习题11:单词出现次数
  • Android kotlin使用Netty网络框架实践(客户端、服务端)
  • 新版Pycharm的Available Packages里面为空,新版没有Manage Repositories功能,如何解决
  • OpenGL/GLUT实践:弹簧-质量-阻尼系统模拟摆动的绳子和布料的物理行为(电子科技大学信软图形与动画Ⅱ实验)
  • 《React Hooks:让你的组件更灵活》
  • Android之电量优化
  • 【论文笔记】Multi-Task Learning as a Bargaining Game
  • 4.3 python 编辑单元格
  • 惠中科技:开启综合光伏清洗新征程
  • 文件包含所用协议实战
  • sql-labs56-60通关攻略
  • 设计模式结构型模式之适配器模式
  • vue3子组件修改父组件传来的值
  • 普元Devops-在云主机上拉取harbor的docker镜像并部署
  • 2017年系统架构师案例分析试题五
  • JVM理论篇(一)
  • Flask的secret_key作用
  • Nginx负载均衡数据流分析