第一个应用 #

创建项目 #

首先,使用 Cargo 创建一个新项目:

bash
cargo new hello_actix
cd hello_actix

添加依赖 #

编辑 Cargo.toml,添加 Actix Web 依赖:

toml
[package]
name = "hello_actix"
version = "0.1.0"
edition = "2021"

[dependencies]
actix-web = "4"

最小示例 #

编辑 src/main.rs

rust
use actix_web::{web, App, HttpResponse, HttpServer, Responder};

async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello, Actix Web!")
}

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

代码解析 #

1. 导入模块 #

rust
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
模块 说明
web Web 相关工具,如路由、提取器
App 应用程序配置
HttpResponse HTTP 响应构建器
HttpServer HTTP 服务器
Responder 响应器 trait

2. 处理函数 #

rust
async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello, Actix Web!")
}

处理函数的特点:

  • 必须是 async 函数
  • 返回实现 Responder trait 的类型
  • 可以接受多个提取器参数

3. 主函数 #

rust
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // ...
}

#[actix_web::main] 宏的作用:

  • 创建 Tokio 运行时
  • 启动异步运行时环境

4. 创建服务器 #

rust
HttpServer::new(|| {
    App::new()
        .route("/", web::get().to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await

执行流程:

text
┌─────────────────────────────────────────────────────────────┐
│                      服务器启动流程                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  HttpServer::new()  ──→  创建服务器实例                       │
│         │                                                    │
│         ▼                                                    │
│  App::new()  ──→  创建应用实例                               │
│         │                                                    │
│         ▼                                                    │
│  .route()  ──→  注册路由                                     │
│         │                                                    │
│         ▼                                                    │
│  .bind()  ──→  绑定地址和端口                                │
│         │                                                    │
│         ▼                                                    │
│  .run()  ──→  启动服务器                                     │
│         │                                                    │
│         ▼                                                    │
│  .await  ──→  等待服务器运行                                 │
│                                                              │
└─────────────────────────────────────────────────────────────┘

运行应用 #

bash
cargo run

输出:

text
Compiling hello_actix v0.1.0
Finished dev [unoptimized + debuginfo] target(s)
Running `target/debug/hello_actix`

访问 http://127.0.0.1:8080/,你将看到:

text
Hello, Actix Web!

添加更多路由 #

让我们添加更多路由来展示不同的功能:

rust
use actix_web::{web, App, HttpResponse, HttpServer, Responder};

async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello, Actix Web!")
}

async fn greet(path: web::Path<String>) -> impl Responder {
    let name = path.into_inner();
    HttpResponse::Ok().body(format!("Hello, {}!", name))
}

async fn health() -> impl Responder {
    HttpResponse::Ok().json(serde_json::json!({
        "status": "healthy",
        "timestamp": chrono::Utc::now().to_rfc3339()
    }))
}

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

需要添加额外依赖:

toml
[dependencies]
actix-web = "4"
serde_json = "1"
chrono = { version = "0.4", features = ["serde"] }

使用属性宏定义路由 #

Actix Web 提供了属性宏来简化路由定义:

rust
use actix_web::{web, App, HttpResponse, HttpServer, Responder};

#[actix_web::get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello, Actix Web!")
}

#[actix_web::get("/greet/{name}")]
async fn greet(path: web::Path<String>) -> impl Responder {
    let name = path.into_inner();
    HttpResponse::Ok().body(format!("Hello, {}!", name))
}

#[actix_web::post("/users")]
async fn create_user() -> impl Responder {
    HttpResponse::Created().json(serde_json::json!({
        "id": 1,
        "name": "New User"
    }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(index)
            .service(greet)
            .service(create_user)
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

属性宏说明 #

说明
#[get("/path")] GET 请求
#[post("/path")] POST 请求
#[put("/path")] PUT 请求
#[delete("/path")] DELETE 请求
#[patch("/path")] PATCH 请求
#[head("/path")] HEAD 请求
#[options("/path")] OPTIONS 请求

响应类型 #

Actix Web 支持多种响应类型:

字符串响应 #

rust
async fn string_response() -> impl Responder {
    "Plain text response"
}

JSON 响应 #

rust
use serde::Serialize;

#[derive(Serialize)]
struct User {
    id: u32,
    name: String,
}

async fn json_response() -> impl Responder {
    HttpResponse::Ok().json(User {
        id: 1,
        name: "Alice".to_string(),
    })
}

HTML 响应 #

rust
async fn html_response() -> impl Responder {
    HttpResponse::Ok()
        .content_type("text/html")
        .body("<h1>Hello, HTML!</h1>")
}

重定向 #

rust
async fn redirect() -> impl Responder {
    HttpResponse::Found()
        .insert_header(("Location", "/new-location"))
        .finish()
}

状态码 #

常用 HTTP 状态码:

rust
async fn status_examples() -> impl Responder {
    HttpResponse::Ok()                    // 200
    HttpResponse::Created()               // 201
    HttpResponse::Accepted()              // 202
    HttpResponse::NoContent()             // 204
    HttpResponse::BadRequest()            // 400
    HttpResponse::Unauthorized()          // 401
    HttpResponse::Forbidden()             // 403
    HttpResponse::NotFound()              // 404
    HttpResponse::InternalServerError()   // 500
}

测试路由 #

使用 curl 测试路由:

bash
# GET 请求
curl http://127.0.0.1:8080/

# 带路径参数
curl http://127.0.0.1:8080/greet/Alice

# POST 请求
curl -X POST http://127.0.0.1:8080/users

# 健康检查
curl http://127.0.0.1:8080/health

多 Worker 配置 #

生产环境通常需要多个 Worker:

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

配置服务器选项 #

rust
use std::time::Duration;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().route("/", web::get().to(index))
    })
    .workers(4)
    .bind("127.0.0.1:8080")?
    .keep_alive(Duration::from_secs(75))  // Keep-Alive 超时
    .client_request_timeout(Duration::from_secs(5))  // 请求超时
    .run()
    .await
}

完整示例 #

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

#[derive(Serialize, Deserialize)]
struct User {
    id: u32,
    name: String,
    email: String,
}

#[actix_web::get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("Welcome to Actix Web!")
}

#[actix_web::get("/users/{id}")]
async fn get_user(path: web::Path<u32>) -> impl Responder {
    let id = path.into_inner();
    HttpResponse::Ok().json(User {
        id,
        name: "Alice".to_string(),
        email: "alice@example.com".to_string(),
    })
}

#[actix_web::post("/users")]
async fn create_user(user: web::Json<User>) -> impl Responder {
    HttpResponse::Created().json(user.into_inner())
}

#[actix_web::get("/health")]
async fn health() -> impl Responder {
    HttpResponse::Ok().json(serde_json::json!({
        "status": "healthy"
    }))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Server running at http://127.0.0.1:8080");
    
    HttpServer::new(|| {
        App::new()
            .service(index)
            .service(get_user)
            .service(create_user)
            .service(health)
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

下一步 #

现在你已经创建了第一个 Actix Web 应用,接下来学习 项目结构,了解如何组织一个大型项目!

最后更新:2026-03-29