Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计异常

actix-webActix 网络

Agent Skill

actix-web 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

480

周安装

20

GitHub Stars

8

下载量

160
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:actix-web(Actix 网络)
来源仓库:https://github.com/ar4mirez/samuel
仓库路径:skills/actix-web
安装命令:
npx skills add https://github.com/ar4mirez/samuel --skill actix-web
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ar4mirez/samuel --skill actix-web

简介

提供 Actix Web 框架最佳实践指导与结构规范。

  • 强调类型安全提取、异步处理与模块化路由设计。actix-web 属于开发类 Skill,可作为该场景下的辅助能力补充。
  • 适用于高性能 Rust Web API 项目开发与维护。
  • 需确保使用 web::Data 注入共享状态而非全局变量。
  • 所有 I/O 操作必须异步化以避免阻塞 Tokio 运行时。

SKILL.md

Actix-web Framework Guide

Applies to: Actix-web 4+, Rust Web APIs, High-Performance Services Complements: .claude/skills/rust-guide/SKILL.md

Core Principles

  1. Type-Safe Extraction: Use extractors (web::Json, web::Path, web::Query) for request data
  2. Thin Handlers: Handlers delegate to services; no business logic in handlers
  3. Structured Errors: Implement ResponseError for all error types; never return raw strings
  4. Shared State via web::Data: Application state is injected, never global
  5. Middleware for Cross-Cutting: Auth, logging, CORS belong in middleware, not handlers

Project Structure

myproject/
├── Cargo.toml
├── src/
│   ├── main.rs                # Entry point, server bootstrap
│   ├── config.rs              # Configuration loading
│   ├── routes.rs              # Route registration
│   ├── handlers/
│   │   ├── mod.rs
│   │   ├── users.rs           # User-related handlers
│   │   └── health.rs          # Health check endpoint
│   ├── models/
│   │   ├── mod.rs
│   │   └── user.rs            # Domain models + DTOs
│   ├── services/
│   │   ├── mod.rs
│   │   └── user_service.rs    # Business logic layer
│   ├── repositories/
│   │   ├── mod.rs
│   │   └── user_repository.rs # Database access layer
│   ├── middleware/
│   │   ├── mod.rs
│   │   └── auth.rs            # Authentication middleware
│   └── errors/
│       ├── mod.rs
│       └── app_error.rs       # Centralized error types
├── tests/
│   └── integration_tests.rs
└── migrations/
  • main.rs bootstraps server, loads config, creates pool, wires routes
  • Business logic lives in services/, not in handlers
  • Database access isolated in repositories/
  • One error enum per crate with ResponseError impl

Dependencies (Cargo.toml)

[dependencies]
actix-web = "4"
actix-rt = "2"
actix-cors = "0.7"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres", "uuid", "chrono"] }
validator = { version = "0.16", features = ["derive"] }
thiserror = "1.0"
anyhow = "1.0"
log = "0.4"
env_logger = "0.10"
tracing = "0.1"
tracing-actix-web = "0.7"
uuid = { version = "1.0", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }

[dev-dependencies]
actix-rt = "2"

Application Entry Point

use actix_cors::Cors;
use actix_web::{middleware, web, App, HttpServer};
use sqlx::postgres::PgPoolOptions;

pub struct AppState {
    pub pool: sqlx::PgPool,
    pub config: config::Config,
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    dotenvy::dotenv().ok();
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    let config = config::Config::load().expect("Failed to load configuration");
    let pool = PgPoolOptions::new()
        .max_connections(10)
        .connect(&config.database_url)
        .await
        .expect("Failed to create database pool");

    sqlx::migrate!("./migrations")
        .run(&pool)
        .await
        .expect("Failed to run migrations");

    let app_state = web::Data::new(AppState {
        pool,
        config: config.clone(),
    });

    HttpServer::new(move || {
        let cors = Cors::default()
            .allow_any_origin()
            .allow_any_method()
            .allow_any_header()
            .max_age(3600);

        App::new()
            .app_data(app_state.clone())
            .wrap(cors)
            .wrap(middleware::Logger::default())
            .wrap(middleware::Compress::default())
            .configure(routes::configure)
    })
    .bind(format!("{}:{}", config.host, config.port))?
    .run()
    .await
}

Routing

use actix_web::web;

pub fn configure(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::scope("/api/v1")
            .route("/health", web::get().to(handlers::health::health_check))
            .service(
                web::scope("/auth")
                    .route("/register", web::post().to(handlers::users::register))
                    .route("/login", web::post().to(handlers::users::login)),
            )
            .service(
                web::scope("/users")
                    .wrap(crate::middleware::auth::AuthMiddleware)
                    .route("", web::get().to(handlers::users::list_users))
                    .route("/{id}", web::get().to(handlers::users::get_user))
                    .route("/{id}", web::put().to(handlers::users::update_user))
                    .route("/{id}", web::delete().to(handlers::users::delete_user)),
            ),
    );
}

Routing Guardrails

  • Group routes by resource under web::scope
  • Apply middleware at the scope level, not per-route
  • Use web::ServiceConfig for modular route registration
  • Version API routes (/api/v1/...)
  • Keep route definitions separate from handler implementations

Extractors

Extractors are how Actix-web injects request data into handler functions.

ExtractorPurposeExample
web::Json<T>Deserialize JSON bodybody: web::Json<CreateDto>
web::Path<T>URL path parameterspath: web::Path<Uuid>
web::Query<T>Query string parametersquery: web::Query<PaginationQuery>
web::Data<T>Shared application statestate: web::Data<AppState>
web::Form<T>URL-encoded form dataform: web::Form<LoginForm>
HttpRequestRaw request (headers, extensions)req: HttpRequest

Extractor Rules

  • Always validate extracted data (use validator crate with Validate derive)
  • Prefer typed extractors over manually parsing HttpRequest
  • Use web::Data for immutable shared state (wrapped in Arc internally)
  • Limit JSON body size with .app_data(web::JsonConfig::default().limit(4096))

Handlers

Handlers are async functions that take extractors and return impl Responder.

use actix_web::{web, HttpResponse};

pub async fn register(
    state: web::Data<AppState>,
    body: web::Json<CreateUserDto>,
) -> AppResult<HttpResponse> {
    let service = UserService::new(state.pool.clone(), state.config.clone());
    let response = service.register(body.into_inner()).await?;
    Ok(HttpResponse::Created().json(response))
}

pub async fn get_user(
    state: web::Data<AppState>,
    path: web::Path<Uuid>,
) -> AppResult<HttpResponse> {
    let service = UserService::new(state.pool.clone(), state.config.clone());
    let user = service.get_user(path.into_inner()).await?;
    Ok(HttpResponse::Ok().json(user))
}

Handler Rules

  • Return Result<HttpResponse, AppError> (aliased as AppResult<HttpResponse>)
  • Use .into_inner() to unwrap extractors before passing to services
  • No business logic in handlers -- delegate to service layer
  • One handler per HTTP method per resource action

Application State

pub struct AppState {
    pub pool: sqlx::PgPool,
    pub config: Config,
}

// Register in HttpServer closure:
let app_state = web::Data::new(AppState { pool, config });
App::new().app_data(app_state.clone())

// Access in handlers:
pub async fn handler(state: web::Data<AppState>) -> impl Responder {
    let pool = &state.pool;
    // use pool...
}

State Rules

  • Wrap in web::Data (internally uses Arc)
  • Clone web::Data in HttpServer::new closure (cheap Arc clone)
  • Keep state immutable; use tokio::sync::RwLock if mutation is required
  • Do not store request-scoped data in AppState

Error Handling

use actix_web::{http::StatusCode, HttpResponse, ResponseError};

#[derive(Debug)]
pub enum AppError {
    NotFound(String),
    BadRequest(String),
    Unauthorized(String),
    Forbidden(String),
    Conflict(String),
    Validation(String),
    Internal(String),
    Database(sqlx::Error),
}

impl ResponseError for AppError {
    fn error_response(&self) -> HttpResponse {
        let (status, message) = match self {
            AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
            AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
            AppError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg.clone()),
            AppError::Forbidden(msg) => (StatusCode::FORBIDDEN, msg.clone()),
            AppError::Conflict(msg) => (StatusCode::CONFLICT, msg.clone()),
            AppError::Validation(msg) => (StatusCode::UNPROCESSABLE_ENTITY, msg.clone()),
            AppError::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error".into()),
            AppError::Database(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Database error".into()),
        };
        HttpResponse::build(status).json(serde_json::json!({
            "success": false,
            "error": { "code": status.as_u16(), "message": message }
        }))
    }
}

pub type AppResult<T> = Result<T, AppError>;

Error Handling Rules

  • Implement ResponseError trait for all custom error types
  • Use From<T> impls for automatic conversion: sqlx::Error, validator::ValidationErrors
  • Log internal/database errors server-side; return generic messages to clients
  • Define AppResult<T> type alias to reduce boilerplate

Middleware

Actix-web middleware uses the Transform + Service traits.

pub struct AuthMiddleware;

impl<S, B> Transform<S, ServiceRequest> for AuthMiddleware
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Transform = AuthMiddlewareService<S>;
    type InitError = ();
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ok(AuthMiddlewareService { service: Rc::new(service) })
    }
}

Middleware Rules

  • Use Transform trait for middleware factories, Service for middleware logic
  • Store authenticated user data in request extensions (req.extensions_mut().insert(...))
  • Apply middleware at scope level: .service(web::scope("/protected").wrap(AuthMiddleware))
  • Use built-in middleware: Logger, Compress, NormalizePath, DefaultHeaders
  • Order matters: middleware wraps from bottom to top (last .wrap() runs first)

Configuration

use serde::Deserialize;

#[derive(Clone, Deserialize)]
pub struct Config {
    pub host: String,
    pub port: u16,
    pub database_url: String,
    pub jwt_secret: String,
    pub jwt_expiration_hours: i64,
}

impl Config {
    pub fn load() -> anyhow::Result<Self> {
        let config = config::Config::builder()
            .add_source(config::Environment::default().separator("__").try_parsing(true))
            .set_default("host", "127.0.0.1")?
            .set_default("port", 8080)?
            .build()?;
        Ok(config.try_deserialize()?)
    }
}

Commands

# Development
cargo run                              # Start server
cargo watch -x run                     # Watch mode (requires cargo-watch)
RUST_LOG=actix_web=debug cargo run     # Debug logging

# Build
cargo build --release                  # Production build
cargo check                            # Fast type-check

# Quality
cargo fmt                              # Format code
cargo clippy -- -D warnings            # Lint with deny
cargo test                             # Run all tests
cargo tarpaulin                        # Coverage

# Database
sqlx migrate run                       # Run migrations
sqlx migrate add <name>                # Create migration

Best Practices

Application Structure

  • Use web::Data for shared application state
  • Organize routes with web::scope and ServiceConfig
  • Service layer for business logic, repository layer for data access
  • Keep handlers thin: extract, delegate, respond

Performance

  • Use connection pooling (sqlx::PgPool or deadpool)
  • Enable middleware::Compress for response compression
  • Use async/await throughout; avoid blocking operations
  • Configure worker count for production: .workers(num_cpus::get())
  • Set JSON payload limits to prevent abuse

Security

  • Validate all inputs with validator crate
  • Use HTTPS in production (terminate at load balancer or use actix-tls)
  • Implement rate limiting (actix-governor or custom middleware)
  • Sanitize error messages: never expose internal details to clients
  • Use actix-cors with explicit origins in production (not allow_any_origin)

Testing

  • Use actix_web::test module for integration tests
  • Create test app with test::init_service and shared test state
  • Assert on status codes, response bodies, and headers
  • Test middleware independently from handlers

Advanced Topics

For detailed patterns and examples, see:

External References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.54%
按下载量换算54

Claude

32.99%
按下载量换算53

Cursor

17.51%
按下载量换算28

Gemini CLI

8.57%
按下载量换算14

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills