| Pattern | Kind | Description |
| ------------------------------- | ------------------- | ------------------------------------------------------------------------------ |
| :name
| Normal
| Matches a path piece, excludes /
|
| :name?
| Optional
| Matches an optional path piece, excludes /
|
| /:name?/
/:name?
| OptionalSegment
| Matches an optional path segment, excludes /
, prefix or suffix should be /
|
| +
:name+
| OneOrMore
| Matches a path piece, includes /
|
| *
:name*
| ZeroOrMore
| Matches an optional path piece, includes /
|
| /*/
/*
/:name*/
/:name*
| ZeroOrMoreSegment
| Matches zero or more path segments, prefix or suffix should be /
````rust use headers::{authorization::Bearer, Authorization}; use hypers::prelude::*; use std::time::Instant; use tracing::info;
pub struct CookieJarParams { pub hypers: String, pub rust: String, }
pub struct HeaderParams {
pub host: Option
pub struct UserController {
pub id: Option
// http://127.0.0.1:7878/api/v1/user
impl UserController {
// Request Cookies
#[get("parsecookies")]
pub async fn parsecookies(req: Request) -> impl Responder {
let cookiejar = req.parsecookies::
// Request Headers
#[get("/parse_header")]
pub async fn parse_header(req: Request) -> impl Responder {
let header_params = req.parse_header::<HeaderParams>()?;
Ok::<_, Error>((200, Json(header_params)))
}
// Url Path Params
#[delete("parse_param/:id/:name/:age")]
pub async fn parse_param(req: Request, id: u32, name: String, age: u16) -> impl Responder {
let app_state = req.get::<Self>("user");
(
200,
format!(
"id = {}, name = {},age = {}\n app_state = {:#?}",
id, name, age, app_state
),
)
}
// Url Path Params
#[get("parse_param2/:id/:email/:age")]
pub async fn parse_param2(req: Request) -> impl Responder {
let user = req.parse_param::<UserController>()?;
user.validate()?; // user will be validate
Ok::<_, Error>((200, Json(user)))
}
// Url Query Params
#[get("/parse_query")] // user will be validate
pub async fn parse_query(query_params: Query<Self>) -> impl Responder {
Ok::<_, Error>((200, Json(query_params.0)))
}
// Context-Type : application/x-www-form-urlencoded
#[get("/parse_form_get")]
#[patch("/parse_form_patch")]
#[validator(exclude("user"))] // user will not be validate
pub async fn parse_form_get(user: Form<UserController>) -> impl Responder {
(200, user)
}
// Context-Type : application/json
#[post("/parse_json")] // user will be validate
pub async fn parse_json(user: Json<UserController>) -> impl Responder {
(200, user)
}
// Context-Type : multipart/form-data Form Fields
#[post("/multipart_form")]
pub async fn multipart_form(mut req: Request) -> impl Responder {
let user = req.parse::<Self>().await?;
user.validate()?; // user will be validate
Ok::<_, Error>((200, Json(user)))
}
// Context-Type : multipart/form-data Files
#[post("/multipart_file")]
pub async fn multipart_file(mut req: Request) -> impl Responder {
let file = req.file("file").await?;
let file_name = file.name()?;
let file_name = file_name.to_string();
let img = req.files("imgs").await?;
let imgs_name = img
.iter()
.map(|m| m.name().unwrap().to_string())
.collect::<Vec<String>>()
.join(",");
Some((
200,
format!("file_name = {}, imgs_name = {}", file_name, imgs_name),
))
}
}
struct BasicController;
// http://127.0.0.1:7878/basic
impl BasicController {
// Request Headers
#[get("/header")]
pub async fn header(req: Request) -> impl Responder {
let host = req.header::
// Url Path Params
#[delete("/param/:name/:age")]
pub async fn param(req: Request) -> impl Responder {
let name = req.param::<String>("name")?;
let age = req.param::<u16>("age")?;
Some((200, format!("name = {} , age = {}", name, age)))
}
// Url Query Params
#[get("/query")]
pub async fn query(req: Request) -> impl Responder {
let name = req.query::<Vec<String>>("name")?;
let age = req.query::<u16>("age")?;
let key = req.get::<&str>("key")?;
Some((
200,
format!("name = {:?} , age = {}\n, app_state = {}", name, age, key),
))
}
#[get("/set_cookies")]
pub async fn set_cookies(_req: Request) -> impl Responder {
let mut cookie1 = Cookie::new("hypers", "hypers2023");
cookie1.set_path("/api/v1/user");
let mut cookie2 = Cookie::new("rust", "rust2023");
cookie2.set_path("/api/v1/user");
let mut cookie_jar = CookieJar::new();
cookie_jar.add(cookie1);
cookie_jar.add(cookie2);
(200, cookie_jar)
}
}
// Websocket ws://127.0.0.1:7878/hello/ws http://www.jsons.cn/websocket/
pub async fn websocket(req: Request, mut ws: WebSocket) -> Result<()> {
let name = req.param::
// Middleware Function pub async fn stattime(req: Request, netx: Next) -> Result { // Before executing the request processing function let starttime = Instant::now();
// Calling subsequent request processing functions
let res = netx.next(req).await?;
// After the execution of the request processing function
let elapsed_time = start_time.elapsed();
println!(
"The current request processing function takes time :{:?}",
elapsed_time
);
Ok(res)
}
// Middleware Function pub async fn logger(req: Request, next: Next) -> Result { // Before executing the request processing function let uri = req.uri().path(); info!("uri = {:?}", uri); // Calling subsequent request processing functions let res = next.next(req).await; // After the execution of the request processing function res }
// Middleware Function pub async fn appstate(mut req: Request, next: Next) -> Result { let user = UserController { id: Some(1), email: Some("admin@gmail.com".toowned()), age: Some(21), }; req.set("user", user); req.set("key", "Hello World"); next.next(req).await }
struct ApiKeyMiddleware { api_key: String, }
pub struct MiddlewareError
// Middleware Macro
impl ApiKeyMiddleware {
async fn hook(&self, req: Request, next: Next) -> Result
// Write router like a tree fn main() -> Result<()> { tracing_subscriber::fmt().compact().init();
// The Root Router
let mut root = Router::new("/");
root.get("/*", StaticDir::new("hypers").listing(true))
.ws(":name/ws", websocket);
// Add Middleware ( Middleware can be added to any routing node )
root.hook(logger, vec!["/basic"], None)
.hook(
app_state,
vec!["/api/v1/user/parse_param/:id/:name/:age", "/basic/query"],
None,
)
.hook(stat_time, vec!["/api/v1/user"], None)
.hook(
ApiKeyMiddleware {
api_key: "hypers".to_owned(),
},
vec!["/basic"],
vec!["/api/v1/user"],
);
// Add sub router to the root router
root.controller(UserController::default());
root.controller(BasicController);
println!("root router = {:#?}", root);
// Registering the root router into the server
let app = hypers::new(root);
app.run("127.0.0.1:7878")
} `````