HTTP Request URL Parameters Syntax
| 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 / |
⚡️ Quick Start
use hypers's full feature
use hypers::prelude::*;
use std::time::Instant;
#[derive(Serialize, Deserialize)]
pub struct User {
pub id: Option<u32>,
pub name: Option<String>,
pub age: Option<u16>,
}
#[derive(Serialize, Deserialize)]
pub struct QueryParams {
pub id: Option<u32>,
pub name: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct PathParams {
pub id: Option<u32>,
pub name: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct HeaderParams {
pub host: Option<String>,
#[serde(rename(deserialize = "user-agent"))]
pub user_agent: Option<String>,
pub accept: Option<String>,
}
pub async fn create(mut req: Request) -> impl Responder {
let user = req.parse_body::<User>().await?;
Ok::<_, Error>((200, Json(user)))
}
pub async fn update(mut req: Request) -> impl Responder {
let user = req.parse_body::<User>().await?;
let id = req.param::<&str>("id");
println!("id = {:?}", id);
Ok::<_, Error>((200, Json(user)))
}
pub async fn query(req: Request) -> impl Responder {
let query_params = req.parse_query::<QueryParams>()?;
Ok::<_, Error>((200, Form(query_params)))
}
pub async fn delete(req: Request) -> impl Responder {
let params = req.parse_param::<PathParams>()?;
Ok::<_, Error>((200,Json(params)))
}
pub async fn delete_one(req: Request) -> impl Responder {
let name = req.param::<String>("name")?;
let age = req.param::<u16>("age")?;
Some((200,format!("name = {} , age = {}",name,age)))
}
pub async fn multipart_form_data(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(",");
let name = req.form::<String>("name").await?;
Some((
200,
format!(
"file_name = {}, imgs_name = {}, name = {}",
file_name, imgs_name, name
),
))
}
pub async fn parse_header(req: Request) -> impl Responder {
let header_params = req.parse_header::<HeaderParams>()?;
Ok::<_, Error>((200, Json(header_params)))
}
pub async fn websocket(req: Request, mut ws: WebSocket) -> Result<()> {
let name = req.param::<String>("name").unwrap_or_default();
while let Ok(msg) = ws.receive().await {
if let Some(msg) = msg {
match msg {
Message::Text(text) => {
let text = format!("{},{}", name, text);
ws.send(Message::Text(text)).await?;
}
Message::Close(_) => break,
_ => {}
}
}
}
Ok(())
}
pub async fn stat_time(req: Request, netx: Next) -> Result {
let start_time = Instant::now();
let res = netx.next(req).await?;
let elapsed_time = start_time.elapsed();
println!(
"The current request processing function takes time :{:?}",
elapsed_time
);
println!(
"The response after the execution of the current request processing function : {:?}",
res.body()
);
Ok(res)
}
pub async fn logger(req: Request, next: Next) -> Result {
let uri = req.uri().path();
println!("uri = {:?}", uri);
let res = next.next(req).await;
res
}
fn main() -> Result<()> {
let mut root = Router::new("/");
root.hook(logger, vec!["/parse_header"], None);
root.get("/*", StaticDir::new("src").listing(true));
root.ws(":name/ws", websocket);
root.get("/parse_header", parse_header);
let mut user = Router::new("user");
user.hook(stat_time, vec!["/user"], None);
user.post("create", create)
.patch("update/:id", update)
.get("query", query)
.delete("delete/:id/:name", delete)
.delete("delete_one/:age/:name", delete_one)
.post("multipart_form_data", multipart_form_data);
root.push(user);
let app = hypers::new(root);
#[cfg(not(any(feature = "rustls", feature = "native_tls")))]
{
app.run("127.0.0.1:7878")
}
#[cfg(feature = "rustls")]
{
let tls = RustlsConfig::new()
.cert(include_bytes!("./certs/cert.pem").to_vec())
.key(include_bytes!("./certs/key.pem").to_vec());
app.run("127.0.0.1:7878", tls)
}
#[cfg(feature = "native_tls")]
{
let tls = NativeTls::from_pkcs12(include_bytes!("./certs/identity.p12"), "mypass")?;
app.run("127.0.0.1:7878", tls)
}
}