Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/silent-middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub struct AddHeaders;
impl MiddleWareHandler for AddHeaders {
async fn handle(&self, req: Request, next: &Next) -> Result<Response> {
let mut res = next.call(req).await?;
res.headers_mut().insert("X-Powered-By", "Silent".parse().unwrap());
res.headers_mut().insert("x-powered-by", "Silent".parse().unwrap());
Ok(res)
}
}
Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/silent-openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

```toml
[dependencies]
silent = "2.15"
silent-openapi = "2.15"
silent-openapi-macros = "2.15"
silent = "2.16"
silent-openapi = "2.16"
silent-openapi-macros = "2.16"
utoipa = { version = "5", features = ["preserve_order"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Expand Down Expand Up @@ -158,7 +158,7 @@ async fn handler(req: Request, Json(body): Json<CreateUser>) -> Result<Response>
## Swagger UI 配置选项

```rust
use silent_openapi::handler::{SwaggerUiHandler, SwaggerUiOptions};
use silent_openapi::{SwaggerUiHandler, SwaggerUiOptions};

let options = SwaggerUiOptions {
try_it_out_enabled: true, // 启用 "Try it out" 交互式调试
Expand Down
6 changes: 2 additions & 4 deletions .claude/skills/silent-project-scaffold.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ tracing = "0.1"
按需添加 features:
- 需要 WebSocket:`silent = { version = "2", features = ["upgrade"] }`
- 需要静态文件:`silent = { version = "2", features = ["static"] }`
- 需要所有功能:`silent = { version = "2", features = ["full"] }`
- 需要 gRPC:`silent = { version = "2", features = ["grpc"] }`
- 需要 SSE:`silent = { version = "2", features = ["sse"] }`
- 需要模板:`silent = { version = "2", features = ["template"] }`
- 需要会话:`silent = { version = "2", features = ["session"] }`

`full`、`grpc`、`template`、`session`、`scheduler`、`security` 和 `admin` 在 2.x 中仍可按需启用。`session`、`scheduler` 和 `admin` 属于兼容保留入口;`security`、`template`、`grpc` 的长期归属由 3.0 RFC 决定。新项目只启用实际需要的 feature,不把 `full` 当作默认项目骨架。

## main.rs 模板

Expand Down
26 changes: 13 additions & 13 deletions .claude/skills/silent-route-handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let route = Route::new_root()
```rust
Route::new("<id>") // 字符串参数
Route::new("<id:i64>") // 整数参数(i64)
Route::new("<id:int>") // 整数参数(同上)
Route::new("<id:int>") // 整数参数(i32)
Route::new("<path:**>") // 通配符(匹配剩余所有路径段)
```

Expand Down Expand Up @@ -70,7 +70,7 @@ async fn json_handler(_req: Request) -> Result<Response> {
### 3. 使用提取器

```rust
use serde::Deserialize;
use serde::{Deserialize, Serialize};

// Path 提取器 — 从路径参数中提取
async fn get_user(Path(id): Path<i64>) -> Result<String> {
Expand Down Expand Up @@ -101,7 +101,7 @@ async fn list(Query(p): Query<Pagination>) -> Result<String> {
// 请求: GET /list?page=1&size=10

// Json 提取器 — 从请求体 JSON 中提取
#[derive(Deserialize)]
#[derive(Deserialize, Serialize)]
struct CreateUser {
name: String,
email: String,
Expand Down Expand Up @@ -173,7 +173,7 @@ let mut res = Response::json(&data);
res.set_status(StatusCode::CREATED);

// 设置响应头
res.headers_mut().insert("X-Custom", "value".parse().unwrap());
res.headers_mut().insert("x-custom", "value".parse().unwrap());

// 字符串和 &str 自动转为 Response
async fn handler(_req: Request) -> Result<&'static str> {
Expand All @@ -196,24 +196,24 @@ let route = Route::new("")
.get(handler);
```

## Configs 配置注入
## State 注入

```rust
// 在路由上设置配置
let mut configs = Configs::default();
configs.insert(DatabasePool::new());

let mut route = Route::new("").get(handler);
route.set_configs(Some(configs));
// 在路由上注入应用级共享状态
let route = Route::new_root()
.with_state(DatabasePool::new())
.get(handler);

// 在处理器中获取配置
// 在处理器中获取状态
async fn handler(req: Request) -> Result<Response> {
let pool = req.get_config::<DatabasePool>()?;
let pool = req.get_state::<DatabasePool>()?;
// 使用 pool...
Ok(Response::empty())
}
```

`Configs`、`set_configs` 和 `get_config` 是 2.x 兼容入口,新代码不要使用;它们最早于 3.0 移除。

## 静态文件服务

```rust
Expand Down
29 changes: 11 additions & 18 deletions .claude/skills/silent-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ edition = "2024"
crate-type = ["cdylib"]

[dependencies]
silent = { version = "2.15", features = ["worker"] }
worker = "0.7"
silent = { version = "2.16", default-features = false, features = ["worker"] }
worker = "0.8"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
console_error_panic_hook = "0.1"
Expand Down Expand Up @@ -76,21 +76,14 @@ use worker::{Context, Env, Request, Response, Result};

#[cfg(target_arch = "wasm32")]
use crate::route::get_route;
#[cfg(target_arch = "wasm32")]
use silent::Configs;

#[cfg(target_arch = "wasm32")]
#[worker::event(fetch)]
pub async fn main(req: Request, env: Env, ctx: Context) -> Result<Response> {
console_error_panic_hook::set_once();

// 将 Env 和 Context 注入到 Configs
// 处理器通过 req.get_config::<Env>() 和 req.get_config::<Context>() 获取
let mut cfg = Configs::default();
cfg.insert(env);
cfg.insert(ctx);

let wr = get_route().with_configs(cfg);
// 将 Env 和 Context 注入到 State
// 处理器通过 req.get_state::<Env>() 和 req.get_state::<Context>() 获取
let wr = get_route().with_state(env).with_state(ctx);
Ok(wr.call(req).await)
}
```
Expand Down Expand Up @@ -122,7 +115,7 @@ async fn hello(_req: Request) -> silent::Result<&'static str> {

```rust
async fn kv_get(req: Request) -> silent::Result<Response> {
let env = req.get_config::<Env>()?;
let env = req.get_state::<Env>()?;
let key: String = req.get_path_params("key")?;
let kv = env.kv("MY_KV").map_err(worker_err)?;

Expand All @@ -137,7 +130,7 @@ async fn kv_get(req: Request) -> silent::Result<Response> {
}

async fn kv_put(mut req: Request) -> silent::Result<Response> {
let env = req.get_config::<Env>()?.clone();
let env = req.get_state::<Env>()?.clone();
let key: String = req.get_path_params("key")?;
let value = read_body_text(&mut req).await?;
let kv = env.kv("MY_KV").map_err(worker_err)?;
Expand All @@ -150,7 +143,7 @@ async fn kv_put(mut req: Request) -> silent::Result<Response> {

```rust
async fn d1_query(req: Request) -> silent::Result<Response> {
let env = req.get_config::<Env>()?;
let env = req.get_state::<Env>()?;
let d1 = env.d1("MY_DB").map_err(worker_err)?;
let stmt = d1.prepare("SELECT id, name FROM users LIMIT 100");
let result = stmt.all().await.map_err(worker_err)?;
Expand All @@ -163,7 +156,7 @@ async fn d1_query(req: Request) -> silent::Result<Response> {

```rust
async fn r2_get(req: Request) -> silent::Result<Response> {
let env = req.get_config::<Env>()?;
let env = req.get_state::<Env>()?;
let key: String = req.get_path_params("key")?;
let bucket = env.bucket("MY_BUCKET").map_err(worker_err)?;

Expand Down Expand Up @@ -236,8 +229,8 @@ wrangler deploy

## 关键注意事项

- Worker 环境下 `Configs` 是只读的,跨请求不保持状态
- Worker 环境下 `State` 只适合保存只读依赖,跨请求不保持可变状态
- 需要持久化请使用 KV / D1 / R2 / Durable Objects
- JSON 请求体可直接使用 `req.json_parse::<T>().await`
- 获取路径参数使用 `req.get_path_params("key")?`
- 获取 Env 时如需可变操作需要 `.clone()`:`req.get_config::<Env>()?.clone()`
- 获取 Env 时如需可变操作需要 `.clone()`:`req.get_state::<Env>()?.clone()`
Loading
Loading