国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【從零開始的rust web開發(fā)之路 一】axum學(xué)習(xí)使用

這篇具有很好參考價(jià)值的文章主要介紹了【從零開始的rust web開發(fā)之路 一】axum學(xué)習(xí)使用。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

系列文章目錄

第一章 axum學(xué)習(xí)使用


前言

本職java開發(fā),兼架構(gòu)設(shè)計(jì)。空閑時(shí)間學(xué)習(xí)了rust,目前還不熟練掌握。想著用urst開發(fā)個(gè)web服務(wù),正好熟悉一下rust語言開發(fā)。
目前rust 語言web開發(fā)相關(guān)的框架已經(jīng)有很多,但還是和java,go語言比不了。
這個(gè)系列想完整走一遍web開發(fā),后續(xù)有時(shí)間就出orm,還有一些別的web用到的庫教程。
言歸正傳,開始學(xué)習(xí)axum框架

老規(guī)矩先看官方文檔介紹

Axum是一個(gè)專注于人體工程學(xué)和模塊化的Web應(yīng)用程序框架。

高級功能

使用無宏 API 將請求路由到處理程序。
使用提取程序以聲明方式分析請求。
簡單且可預(yù)測的錯(cuò)誤處理模型。
使用最少的樣板生成響應(yīng)。
充分利用塔和塔-http生態(tài)系統(tǒng) 中間件、服務(wù)和實(shí)用程序。
特別是,最后一點(diǎn)是與其他框架的區(qū)別。 沒有自己的中間件系統(tǒng),而是使用tower::Service。這意味著獲得超時(shí)、跟蹤、壓縮、 授權(quán)等等,免費(fèi)。它還使您能夠與 使用 hyper 或 tonic 編寫的應(yīng)用程序。axumaxumaxum

兼容性

Axum旨在與Tokio和Hyper配合使用。運(yùn)行時(shí)和 傳輸層獨(dú)立性不是目標(biāo),至少目前是這樣。

tokio框架在rust異步當(dāng)中相當(dāng)流行。axum能很好地搭配tokio實(shí)現(xiàn)異步web

二、hello world

看看官方例子

use axum::{
    routing::get,
    Router,
};

#[tokio::main]
async fn main() {
    // 構(gòu)建router
    let app = Router::new().route("/", get(|| async { "Hello, World!" }));

    // 運(yùn)行hyper  http服務(wù) localhost:3000
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

要想使用還需要引入庫

[dependencies]
axum = "0.6.19"
tokio = { version = "1.29.1", features = ["full"] }
tower = "0.4.13"

這時(shí)候就可以運(yùn)行了,訪問localhost:3000此時(shí)就能在頁面看到Hello, World!

三、路由

路由設(shè)置路徑有哪些handler去處理
handler可以理解為springboot開發(fā)當(dāng)中的controller里面的方法

use axum::{Router, routing::get};

// our router
let app = Router::new()
    .route("/", get(root))  //路徑對應(yīng)handler
    .route("/foo", get(get_foo).post(post_foo))
    .route("/foo/bar", get(foo_bar));

// 一個(gè)個(gè)handler
async fn root() {}
async fn get_foo() {}
async fn post_foo() {}
async fn foo_bar() {}

創(chuàng)建路由

Router::new()

說一些常用方法
nest方法可以嵌套一些別的路由

use axum::{
    routing::{get, post},
    Router,
};
let user_routes = Router::new().route("/:id", get(|| async {}));
let team_routes = Router::new().route("/", post(|| async {}));

let api_routes = Router::new()
    .nest("/users", user_routes)
    .nest("/teams", team_routes);

let app = Router::new().nest("/api", api_routes);
//此時(shí)有兩個(gè)路徑
// - GET /api/users/:id
// - POST /api/teams

其實(shí)就大致相當(dāng)于springboot當(dāng)中在controller類上設(shè)置總路徑。
merge方法將兩個(gè)路由器合并為一個(gè)

use axum::{
    routing::get,
    Router,
};

// user路由
let user_routes = Router::new()
    .route("/users", get(users_list))
    .route("/users/:id", get(users_show));
// team路由
let team_routes = Router::new()
    .route("/teams", get(teams_list));

// 合并
let app = Router::new()
    .merge(user_routes)
    .merge(team_routes);

//  此時(shí)接受請求
// - GET /users
// - GET /users/:id
// - GET /teams

router可以接受多個(gè)handler方法,對于不同的請求方式

use axum::{Router, routing::{get, delete}, extract::Path};
let app = Router::new().route(
    "/",
    get(get_root).post(post_root).delete(delete_root),
);
async fn get_root() {}
async fn post_root() {}
async fn delete_root() {}

如果你之前用過go語言中的gin框架,那么上手這個(gè)會簡單很多

四,handler和提取器

handler是一個(gè)異步函數(shù),它接受零個(gè)或多個(gè)“提取器”作為參數(shù)并返回一些 可以轉(zhuǎn)換為響應(yīng)。
處理程序是應(yīng)用程序邏輯所在的位置,也是構(gòu)建 axum 應(yīng)用程序的位置 通過在處理程序之間路由。
它采用任意數(shù)量的 “提取器”作為參數(shù)。提取器是實(shí)現(xiàn) FromRequest 或 FromRequestPart 的類型

例如,Json 提取器,它使用請求正文和 將其反序列化為 JSON 為某種目標(biāo)類型,可以用來解析json格式

use axum::{
    extract::Json,
    routing::post,
    handler::Handler,
    Router,
};
use serde::Deserialize;
#[derive(Deserialize)]
struct CreateUser {
    email: String,
    password: String,
}
async fn create_user(Json(payload): Json<CreateUser>) {
    // 這里payload參數(shù)類型為CreateUser結(jié)構(gòu)體,并且字段參數(shù)已經(jīng)被賦值
}
let app = Router::new().route("/users", post(create_user));

注意需要引入serde 依賴

serde = { version = "1.0.176", features = ["derive"] }
serde_json = "1.0.104"

還有一些其他的常用的提取器,用于解析不同類型參數(shù)

use axum::{
    extract::{Json, TypedHeader, Path, Extension, Query},
    routing::post,
    headers::UserAgent,
    http::{Request, header::HeaderMap},
    body::{Bytes, Body},
    Router,
};
use serde_json::Value;
use std::collections::HashMap;

// `Path`用于解析路徑上的參數(shù),比如/path/:user_id,這時(shí)候請求路徑/path/100,那么user_id的值就是100,類似springboot當(dāng)中@PathVariable注解
async fn path(Path(user_id): Path<u32>) {}

// 查詢路徑請求參數(shù)值,這里轉(zhuǎn)換成hashmap對象了,類似springboot當(dāng)中@RequestParam注解
async fn query(Query(params): Query<HashMap<String, String>>) {}

// `HeaderMap`可以獲取所有請求頭的值
async fn headers(headers: HeaderMap) {}

//TypedHeader可以用于提取單個(gè)標(biāo)頭(header),請注意這需要您啟用了axum的headers功能
async fn user_agent(TypedHeader(user_agent): TypedHeader<UserAgent>) {}

//獲得請求體中的數(shù)據(jù),按utf-8編碼
async fn string(body: String) {}

//獲得請求體中的數(shù)據(jù),字節(jié)類型
async fn bytes(body: Bytes) {}

//這個(gè)使json類型轉(zhuǎn)換成結(jié)構(gòu)體,上面的例子講了
async fn json(Json(payload): Json<Value>) {}

// 這里可以獲取Request,可以自己去實(shí)現(xiàn)更多功能
async fn request(request: Request<Body>) {}

//Extension從"請求擴(kuò)展"中提取數(shù)據(jù)。這里可以獲得共享狀態(tài)
async fn extension(Extension(state): Extension<State>) {}

//程序的共享狀態(tài),需要實(shí)現(xiàn)Clone
#[derive(Clone)]
struct State { /* ... */ }

let app = Router::new()
    .route("/path/:user_id", post(path))
    .route("/query", post(query))
    .route("/user_agent", post(user_agent))
    .route("/headers", post(headers))
    .route("/string", post(string))
    .route("/bytes", post(bytes))
    .route("/json", post(json))
    .route("/request", post(request))
    .route("/extension", post(extension));

每個(gè)handler參數(shù)可以使用多個(gè)提取器提取參數(shù)

use axum::{
    extract::{Path, Query},
    routing::get,
    Router,
};
use uuid::Uuid;
use serde::Deserialize;

let app = Router::new().route("/users/:id/things", get(get_user_things));

#[derive(Deserialize)]
struct Pagination {
    page: usize,
    per_page: usize,
}

impl Default for Pagination {
    fn default() -> Self {
        Self { page: 1, per_page: 30 }
    }
}

async fn get_user_things(
    Path(user_id): Path<Uuid>,
    pagination: Option<Query<Pagination>>,
) {
    let Query(pagination) = pagination.unwrap_or_default();

    // ...
}

提取器的順序
提取程序始終按函數(shù)參數(shù)的順序運(yùn)行,從左到右。
請求正文是只能使用一次的異步流。 因此,只能有一個(gè)使用請求正文的提取程序
例如


use axum::Json;
use serde::Deserialize;

#[derive(Deserialize)]
struct Payload {}

async fn handler(
    // 這種是不被允許的,body被處理了兩次
    string_body: String,
    json_body: Json<Payload>,
) {
    // ...
}

那么如果參數(shù)是可選的需要這么多,使用Option包裹

use axum::{
    extract::Json,
    routing::post,
    Router,
};
use serde_json::Value;

async fn create_user(payload: Option<Json<Value>>) {
    if let Some(payload) = payload {
    } else {
    }
}

let app = Router::new().route("/users", post(create_user));

五,響應(yīng)

響應(yīng)內(nèi)容只要是實(shí)現(xiàn) IntoResponse就能返回

use axum::{
    Json,
    response::{Html, IntoResponse},
    http::{StatusCode, Uri, header::{self, HeaderMap, HeaderName}},
};

// 空的
async fn empty() {}

// 返回string,此時(shí)`text/plain; charset=utf-8` content-type
async fn plain_text(uri: Uri) -> String {
    format!("Hi from {}", uri.path())
}

// 返回bytes`application/octet-stream` content-type
async fn bytes() -> Vec<u8> {
    vec![1, 2, 3, 4]
}

// 返回json格式
async fn json() -> Json<Vec<String>> {
    Json(vec!["foo".to_owned(), "bar".to_owned()])
}

// 返回html網(wǎng)頁格式`text/html` content-type
async fn html() -> Html<&'static str> {
    Html("<p>Hello, World!</p>")
}

// 返回響應(yīng)碼,返回值空
async fn status() -> StatusCode {
    StatusCode::NOT_FOUND
}

// 返回值的響應(yīng)頭
async fn headers() -> HeaderMap {
    let mut headers = HeaderMap::new();
    headers.insert(header::SERVER, "axum".parse().unwrap());
    headers
}

// 數(shù)組元組設(shè)置響應(yīng)頭
async fn array_headers() -> [(HeaderName, &'static str); 2] {
    [
        (header::SERVER, "axum"),
        (header::CONTENT_TYPE, "text/plain")
    ]
}

// 只要是實(shí)現(xiàn)IntoResponse 都可以返回
async fn impl_trait() -> impl IntoResponse {
    [
        (header::SERVER, "axum"),
        (header::CONTENT_TYPE, "text/plain")
    ]
}

關(guān)于自定義IntoResponse,看看ai怎么說

要自定義實(shí)現(xiàn)IntoResponse,按照以下步驟進(jìn)行:
創(chuàng)建一個(gè)實(shí)現(xiàn)http::Response的結(jié)構(gòu)體,該結(jié)構(gòu)體將承載您的自定義響應(yīng)對象。
創(chuàng)建一個(gè)impl塊,實(shí)現(xiàn)IntoResponse trait。
在into_response方法中,根據(jù)需要生成您的自定義響應(yīng)。

use axum::{http::{Response, StatusCode}, into_response::IntoResponse, response::Html};

// 創(chuàng)建一個(gè)自定義響應(yīng)對象
struct MyResponse(String);

// 創(chuàng)建一個(gè)impl塊,實(shí)現(xiàn)`IntoResponse` trait
impl IntoResponse for MyResponse {
    type Body = Html<String>;
    type Error = std::convert::Infallible;

    fn into_response(self) -> Response<Self::Body> {
        // 根據(jù)需要生成您的自定義響應(yīng)
        Response::builder()
            .status(StatusCode::OK)
            .header("Content-Type", "text/html")
            .body(Html(self.0))
            .unwrap()
    }
}
 

在上面的代碼中,我們實(shí)現(xiàn)了一個(gè)名為MyResponse的自定義響應(yīng)對象,并為其實(shí)現(xiàn)了IntoResponse trait。在into_response方法中,我們將自定義響應(yīng)對象轉(zhuǎn)換為一個(gè)HTML響應(yīng),并返回。

您可以像下面這樣使用這個(gè)自定義響應(yīng)對象:文章來源地址http://www.zghlxwxcb.cn/news/detail-656030.html

async fn my_handler() -> impl IntoResponse {
   MyResponse("<h1>Hello, Axum!</h1>".to_string())
}

到了這里,關(guān)于【從零開始的rust web開發(fā)之路 一】axum學(xué)習(xí)使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【W(wǎng)eb】從零開始的js逆向?qū)W習(xí)筆記(上)

    【W(wǎng)eb】從零開始的js逆向?qū)W習(xí)筆記(上)

    目錄 一、逆向基礎(chǔ) 1.1 語法基礎(chǔ) 1.2 作用域 1.3 窗口對象屬性 1.4 事件 二、瀏覽器控制臺 2.1 Network Network-Headers Network-Header-General Network-Header-Response Headers Network-Header-Request Headers 2.2 Sources 2.3 Application 2.4 Console 三、加密參數(shù)的定位方法 3.1 巧用搜索 3.2 堆棧調(diào)試 3.3 控制臺調(diào)試 3.

    2024年02月21日
    瀏覽(29)
  • 【C語言】從零開始學(xué)習(xí)數(shù)組

    【C語言】從零開始學(xué)習(xí)數(shù)組

    ??博客主頁:江池俊的博客 ?收錄專欄:C語言初階之路 ??其他專欄:數(shù)據(jù)結(jié)構(gòu)探索 ??代碼倉庫:江池俊的代碼倉庫 ?? 社區(qū):GeekHub社區(qū)?(歡迎大家加入與我一起探討學(xué)習(xí)經(jīng)驗(yàn)) ?? 如果覺得博主的文章還不錯(cuò)的話,請點(diǎn)贊??收藏?? 三連支持一下博主?? 目錄 一、一維數(shù)

    2024年02月15日
    瀏覽(17)
  • 從零開始學(xué)習(xí)go開發(fā)

    1.Go 語言的特點(diǎn)和優(yōu)勢 Go 語言是一門相對年輕的編程語言,它具有以下特點(diǎn)和優(yōu)勢: 并發(fā)編程能力:Go 語言天生支持并發(fā)編程,使用 goroutine 和 channel 可以輕松實(shí)現(xiàn)并發(fā)操作,讓編程更加高效。 高效的內(nèi)存管理:Go 語言使用垃圾回收機(jī)制進(jìn)行內(nèi)存管理,省去了手動管理內(nèi)存的

    2024年02月15日
    瀏覽(20)
  • 從零開始學(xué)習(xí)R語言編程:完全指南

    R語言是一種流行的數(shù)據(jù)分析語言,廣泛應(yīng)用于學(xué)術(shù)界、商業(yè)界和社會科學(xué)研究等領(lǐng)域。與其它數(shù)據(jù)分析軟件相比,R語言的優(yōu)點(diǎn)包括免費(fèi)開源、高效可靠、具有強(qiáng)大的數(shù)據(jù)分析和可視化能力等。R語言的編程基礎(chǔ)包括了各種控制結(jié)構(gòu)和函數(shù),可以方便地實(shí)現(xiàn)算法和數(shù)據(jù)操作。本

    2024年02月10日
    瀏覽(31)
  • 【W(wǎng)eb項(xiàng)目實(shí)戰(zhàn)】從零開始學(xué)習(xí)Web自動化測試:用Python和Selenium實(shí)現(xiàn)網(wǎng)站登錄功能

    【W(wǎng)eb項(xiàng)目實(shí)戰(zhàn)】從零開始學(xué)習(xí)Web自動化測試:用Python和Selenium實(shí)現(xiàn)網(wǎng)站登錄功能

    B站首推!2023最詳細(xì)自動化測試合集,小白皆可掌握,讓測試變得簡單、快捷、可靠 https://www.bilibili.com/video/BV1ua4y1V7Db 目錄 1.環(huán)境搭建

    2024年02月06日
    瀏覽(47)
  • FPGA 開發(fā)必備:從零開始學(xué)習(xí) FPGA 設(shè)計(jì)

    FPGA 開發(fā)必備:從零開始學(xué)習(xí) FPGA 設(shè)計(jì) FPGA 是一種可編程邏輯器件,可以在不用重新設(shè)計(jì)硬件電路的情況下修改其功能。它是數(shù)字電路設(shè)計(jì)中最重要的組成部分之一。FPGA 的廣泛應(yīng)用領(lǐng)域包括通信、計(jì)算機(jī)、圖像處理、音頻處理等。 要想成為一名合格的 FPGA 工程師,你需要了

    2024年02月07日
    瀏覽(33)
  • 從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能④

    從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能④

    ??????個(gè)人簡介:以山河作禮。 ??????: Python領(lǐng)域新星創(chuàng)作者,CSDN實(shí)力新星認(rèn)證,阿里云社區(qū)專家博主 ????:Web全棧開發(fā)專欄:《Web全棧開發(fā)》免費(fèi)專欄,歡迎閱讀! ?? JavaScript 可用來在數(shù)據(jù)被送往服務(wù)器前對 HTML 表單中的這些輸入數(shù)據(jù)進(jìn)行驗(yàn)證。 表單數(shù)據(jù)經(jīng)常需

    2024年02月08日
    瀏覽(28)
  • 從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能①

    從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能①

    ??????個(gè)人簡介:以山河作禮。 ??????: Python領(lǐng)域新星創(chuàng)作者,CSDN實(shí)力新星認(rèn)證,阿里云社區(qū)專家博主 ????:Web全棧開發(fā)專欄:《Web全棧開發(fā)》免費(fèi)專欄,歡迎閱讀! ???? JavaScript 是一種腳本語言,用于在 Web 頁面上執(zhí)行交互式操作和動態(tài)效果 。它最初由 Brendan

    2024年02月07日
    瀏覽(27)
  • 從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能⑤

    從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能⑤

    ??????個(gè)人簡介:以山河作禮。 ??????: Python領(lǐng)域新星創(chuàng)作者,CSDN實(shí)力新星認(rèn)證,阿里云社區(qū)專家博主 ????:Web全棧開發(fā)專欄:《Web全棧開發(fā)》免費(fèi)專欄,歡迎閱讀! ???? 在 JavaScript 中,函數(shù)可以通過 function 來定義 。 ?? 函數(shù)定義的一般語法如下: 其中,

    2024年02月08日
    瀏覽(32)
  • 從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能②

    從零開始學(xué)習(xí)JavaScript:輕松掌握編程語言的核心技能②

    ??????個(gè)人簡介:以山河作禮。 ??????: Python領(lǐng)域新星創(chuàng)作者,CSDN實(shí)力新星認(rèn)證,阿里云社區(qū)專家博主 ????:Web全棧開發(fā)專欄:《Web全棧開發(fā)》免費(fèi)專欄,歡迎閱讀! ?? ?? JavaScript 函數(shù)是一段可以被重復(fù)調(diào)用的代碼塊。它可以接收輸入?yún)?shù),處理這些參數(shù),然后返

    2024年02月08日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包