````rust use askama::Template; use athene::prelude::*; use athene::{html, json, status}; use headers::authorization::Bearer; use headers::Authorization; use serde::{Deserialize, Serialize}; use tracing::info;
use validator::{Validate, ValidationError};
pub struct User {
#[validate(email)]
pub username: String,
#[validate(range(min = 18, max = 20))]
pub age: u16,
#[validate(custom = "validateuserrole")]
pub role: Option
fn validateuserrole(role: &str) -> Result<(), ValidationError> { if role.ne("student") { return Err(ValidationError::new("invalid role")); } Ok(()) }
// ================================ Basic Controller ===================================
pub struct AtheneController { pub label: String, pub keyword: String, }
impl Controller for AtheneController { const BASE_PATH: &'static str = "/api/v1/athene";
fn method(&self) -> Vec<ControllerMethod<Self>>
where
Self: Sized,
{
let r = ControllerBuilder::new();
r.get("/index", |_, _req: Request| async {
"athene is a simple and lightweight rust web framework based on Hyper"
})
.post("/add", Self::add)
.delete("/{label}/{keyword}", Self::delete)
.put("/update", Self::update)
.get("/get", Self::get)
.build()
}
}
impl AtheneController {
pub async fn add(&self, mut req: Request) -> impl Responder {
let obj = req.parse::
pub async fn delete(&self, mut req: Request) -> impl Responder {
let lable = req.param("label");
let keyword = req.param("keyword");
/*
...
*/
info!("{}, .... {}", lable, keyword);
(200, "delete success")
}
async fn update(&self, mut req: Request) -> impl Responder {
if let Ok(obj) = req.body_mut().parse::<Form<Self>>().await {
/*
...
*/
info!("{:#?}", obj);
(200, String::from("update success"))
} else {
(400, String::from("update failed"))
}
}
async fn get(&self, req: Request) -> impl Responder {
#[derive(Deserialize, Serialize)]
struct QueryParam<'a> {
label: &'a str,
keyword: &'a str,
}
let arg = req.query::<QueryParam>()?;
/*
...
*/
let res = json!(&arg);
Ok::<_, Error>(res)
}
}
// ================================ Macro Controller =================================== pub struct UserController {}
// http://127.0.0.1:7878/api/v1/user
impl UserController { #[get("//*")] pub async fn matchanyroute(&self, req: Request) -> impl Responder { let uripath = req.uri().path().tostring(); let method = req.method().tostring(); (200, format!("uri : {}, method: {}", uripath, method)) }
#[delete("/{username}/{age}")]
pub async fn delete_by_param(&self, username: String, age: Option<u16>) -> impl Responder {
(
200,
format!("username is : {}, and age is : {:?}", username, age),
)
}
#[get("/get_query_1")]
pub async fn get_query_1(&self, username: String, age: u16) -> impl Responder {
(
200,
Json(User {
username,
age,
role: None,
}),
)
}
#[get("/get_query_2")]
pub async fn get_query_2(&self, request: Request) -> impl Responder {
let user = request.query::<User>()?;
Ok::<_, Error>((200, Json(user)))
}
// Context-Type : application/json
#[post("/post_json")]
#[validator] // The user parameter will be validated
pub async fn post_json(&self, user: Json<User>) -> impl Responder {
Ok::<_,Error>((200, user))
}
// Context-Type : application/x-www-form-urlencoded
#[get("/user_form")]
#[post("/user_form")]
#[validator(exclude("user"))] // The user parameter will not be validated
async fn user_form(&self, user: Form<User>) -> impl Responder {
(200, user)
}
// Context-Type : application/json Or application/x-www-form-urlencoded
// Context-Type : application/msgpack Or application/cbor
#[post("/parse_body")]
#[validator] // User will be validated
async fn parse_body(&self, mut req: Request) ->impl Responder{
let user = req.parse::<User>().await?;
Ok::<_,Error>((
200,
format!("username = {} and age = {}", user.username, user.age),
))
}
// Context-Type : application/multipart-formdata
#[post("/files")]
async fn files(&self, mut req: Request) ->impl Responder {
let files = req.files("files").await?;
let fist_file_name = files[0].name().unwrap();
let second_file_name = files[1].name().unwrap();
let third_file_name = files[2].name().unwrap();
Ok::<_,Error>((
200,
format!(
"fist {}, second {}, third {}",
fist_file_name, second_file_name, third_file_name
),
))
}
}
// ================================ Middleware ====================== struct ApiKeyMiddleware { api_key: String, }
impl ApiKeyMiddleware {
async fn next(&self, ctx: Context, chain: &dyn Next) -> Result
async fn logmiddleware(ctx: Context, next: &'static dyn Next) -> Result
let ctx = next.next(ctx).await?;
info!(
"new response with status: {}",
ctx.state.response_unchecked().status()
);
Ok(ctx)
}
// ================================ Handler ===================================
pub async fn hello(_req: Request) -> impl Responder { (200, "Hello, World!") }
pub async fn user_params(mut req: Request) -> impl Responder {
let username = req.param("username");
let age = req.param("age");
let age = age.parse::
pub async fn login(mut req: Request) -> impl Responder {
if let Ok(user) = req.body_mut().parse::
pub async fn signup(mut req: Request) -> impl Responder { let user = req.bodymut().parse::
"#; ````