salvo-basic-app
Create basic Salvo web applications with handlers, routers, and server setup. Use when starting a new Salvo project or adding basic HTTP endpoints.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create basic Salvo web applications with handlers, routers, and server setup. Use when starting a new Salvo project or adding basic HTTP endpoints.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Guide for using RBatis v4 Rust ORM framework. Use when implementing database CRUD operations, writing dynamic SQL with py_sql or html_sql macros, configuring database connections, managing transactions, implementing interceptors, syncing table structures, or integrating RBatis into Genies microservices. Also use when the user asks about RBatis usage patterns, query building, or database operations in Rust.
Genies 前后端接口规范。Use when designing API contracts, defining field naming conventions, date/time formats, response models, pagination, error handling, or ID strategies between Genies backend and frontend (Web/Android/OHOS).
Guide for using flyway-rs database migration framework with RBatis. Use when implementing database schema migrations, managing SQL changelog files, configuring migration runners, handling multi-database migrations, or integrating database versioning into Genies microservices.
Guide for developing Rust microservices using Genies framework following Java DDD layering principles. Use when creating new microservices, designing aggregate roots, implementing domain events, organizing service layers, setting up Flyway migrations, or structuring a DDD-based Genies project.
Genies framework unified skill hub. Use when you need to find the right skill for any Genies framework task, including authentication, authorization, caching, configuration, database, DDD microservices, Dapr messaging, macros, K8s deployment, testing, API conventions, gateway proxy, or Salvo web framework features. Also use when the user asks about Genies framework capabilities, asks which skill to use, or wants a quick overview of available Genies skills.
Guide for using the Genies Rust microservice framework with DDD and Dapr. Use when developing with Genies, creating aggregates, domain events, Dapr subscriptions, Casbin field-level permissions, configuration management, or when the user asks about Genies framework usage patterns.
| name | salvo-basic-app |
| description | Create basic Salvo web applications with handlers, routers, and server setup. Use when starting a new Salvo project or adding basic HTTP endpoints. |
| version | 0.89.3 |
| tags | ["core","getting-started","handler","router"] |
This skill helps create basic Salvo web applications with proper structure and best practices.
Handlers process HTTP requests. Use the #[handler] macro on async functions:
use salvo::prelude::*;
#[handler]
async fn hello() -> &'static str {
"Hello World"
}
#[handler]
async fn greet(req: &mut Request) -> String {
let name = req.query::<String>("name").unwrap_or("World".to_string());
format!("Hello, {}!", name)
}
Handler parameters can be in any order and are all optional:
req: &mut Request - HTTP request objectres: &mut Response - HTTP response objectdepot: &mut Depot - Request-scoped data storagectrl: &mut FlowCtrl - Flow control for middlewareRouters define URL paths and attach handlers:
use salvo::prelude::*;
let router = Router::new()
.get(hello)
.push(Router::with_path("greet").get(greet));
Basic server configuration:
use salvo::prelude::*;
#[handler]
async fn hello() -> &'static str {
"Hello World"
}
#[tokio::main]
async fn main() {
let router = Router::new().get(hello);
let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;
Server::new(acceptor).serve(router).await;
}
Handlers can return any type implementing Writer or Scribe:
use salvo::prelude::*;
#[handler]
async fn json_response() -> Json<serde_json::Value> {
Json(serde_json::json!({"status": "ok"}))
}
#[handler]
async fn text_response() -> &'static str {
"Plain text response"
}
#[handler]
async fn html_response(res: &mut Response) {
res.render(salvo::writing::Html("<h1>Hello</h1>"));
}
#[handler]
async fn status_response() -> StatusCode {
StatusCode::NO_CONTENT
}
#[handler]
async fn redirect_response(res: &mut Response) {
res.render(salvo::writing::Redirect::found("https://example.com"));
}
use salvo::prelude::*;
use serde::Serialize;
#[derive(Serialize)]
struct User {
name: String,
age: u8,
}
#[handler]
async fn get_user() -> Json<User> {
Json(User {
name: "Alice".to_string(),
age: 30,
})
}
Return Result<T, E> where both implement Writer:
use salvo::prelude::*;
#[handler]
async fn may_fail() -> Result<Json<Data>, StatusError> {
let data = fetch_data().await.map_err(|_| StatusError::internal_server_error())?;
Ok(Json(data))
}
#[handler]
async fn handle_request(req: &mut Request) -> String {
// Get request method
let method = req.method();
// Get request URI
let uri = req.uri();
// Get header value
if let Some(content_type) = req.header::<String>("Content-Type") {
println!("Content-Type: {}", content_type);
}
// Get query parameter
let name = req.query::<String>("name").unwrap_or_default();
// Get path parameter (requires route like /users/{id})
let id = req.param::<i64>("id").unwrap();
// Parse JSON body
let body: UserData = req.parse_json().await.unwrap();
format!("Processed request")
}
use salvo::prelude::*;
#[handler]
async fn handle_response(res: &mut Response) {
// Set status code
res.status_code(StatusCode::CREATED);
// Set response header
res.headers_mut().insert("X-Custom-Header", "value".parse().unwrap());
// Render text response
res.render("Hello, World!");
}
Add to Cargo.toml:
[dependencies]
salvo = "0.89.3"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
#[handler] macro for all handlersTcpListener for basic HTTP servershoop()