use axum::{
Router, Json,
extract::{Path, State},
http::StatusCode,
routing::{get, post, put, delete},
};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
#[derive(Serialize, Deserialize, Clone)]
struct User {
id: u32,
name: String,
email: String,
}
type Db = Arc<Mutex<Vec<User>>>;
async fn list_users(State(db): State<Db>) -> Json<Vec<User>> {
let users = db.lock().unwrap();
Json(users.clone())
}
async fn create_user(
State(db): State<Db>,
Json(input): Json<CreateUser>,
) -> (StatusCode, Json<User>) {
let mut users = db.lock().unwrap();
let user = User {
id: users.len() as u32 + 1,
name: input.name,
email: input.email,
};
users.push(user.clone());
(StatusCode::CREATED, Json(user))
}
async fn get_user(
State(db): State<Db>,
Path(id): Path<u32>,
) -> Result<Json<User>, StatusCode> {
let users = db.lock().unwrap();
users.iter()
.find(|u| u.id == id)
.cloned()
.map(Json)
.ok_or(StatusCode::NOT_FOUND)
}
fn app() -> Router {
let db: Db = Arc::new(Mutex::new(vec![]));
Router::new()
.route("/users", get(list_users).post(create_user))
.route("/users/{id}", get(get_user))
.with_state(db)
}
use axum::{extract::FromRequestParts, http::request::Parts};
struct AuthUser {
user_id: u32,
}
impl<S> FromRequestParts<S> for AuthUser
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let token = parts.headers.get("Authorization")
.and_then(|v| v.to_str().ok())
.ok_or(StatusCode::UNAUTHORIZED)?;
Ok(AuthUser { user_id: 1 })
}
}
async fn protected_route(AuthUser { user_id }: AuthUser) -> String {
format!("用户 {} 已认证", user_id)
}