Expand description
A macro to convert a function to rweb handler.
All parameters should satisfy one of the following.
- Has a path parameter with same name.
- Annotated with the annotations documented below.
- Has a type which implements FromRequest.
§Path parmeters
§Attributes on function item
§#[header("content-type", "application/json")]
Make a route matches only if value of the header matches provided value.
use rweb::*;
#[get("/")]
#[header("accept", "*/*")]
fn routes() -> &'static str {
"This route matches only if accept header is '*/*'"
}
fn main() {
serve(routes());
}
§#[cors]
use rweb::*;
#[get("/")]
#[cors(origins("example.com"), max_age = 600)]
fn cors_1() -> String {
unreachable!()
}
#[get("/")]
#[cors(origins("example.com"), methods(get), max_age = 600)]
fn cors_2() -> String {
unreachable!()
}
#[get("/")]
#[cors(origins("*"), methods(get), max_age = 600)]
fn cors_3() -> String {
unreachable!()
}
#[get("/")]
#[cors(
origins("*"),
methods(get, post, patch, delete),
headers("accept"),
max_age = 600
)]
fn cors_4() -> String {
unreachable!()
}
§#[body_size(max = "8192")]
use rweb::*;
#[get("/")]
#[body_size(max = "8192")]
fn body_size() -> String {
unreachable!()
}
§Attributes on parameters
§#[body]
Parses request body. Type is bytes::Bytes
.
use rweb::*;
use http::Error;
use bytes::Bytes;
#[post("/body")]
fn body(#[body] body: Bytes) -> Result<String, Error> {
let _ = body;
Ok(String::new())
}
fn main() {
serve(body());
}
§#[form]
Parses request body. Content-Type
should be x-www-form-urlencoded
.
use rweb::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct LoginForm {
id: String,
password: String,
}
#[post("/form")]
fn form(#[form] body: LoginForm) -> String {
String::from("Ok")
}
fn main() {
serve(form());
}
§#[json]
Parses request body. Content-Type
should be application/json
.
use rweb::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct LoginForm {
id: String,
password: String,
}
#[post("/json")]
fn json(#[json] body: LoginForm) -> String {
String::from("Ok")
}
fn main() {
serve(json());
}
Note that you can mix the order of parameters.
use rweb::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct LoginForm {
id: String,
password: String,
}
#[get("/param/{a}/{b}")]
fn body_between_path_params(a: u32, #[json] body: LoginForm, b: u32) ->
String { assert_eq!(body.id, "TEST_ID");
assert_eq!(body.password, "TEST_PASSWORD");
(a + b).to_string()
}
fn main() {
serve(body_between_path_params());
}
§#[query]
Parses query string.
use rweb::*;
#[get("/")]
fn use_query(#[query] qs: String) -> String {
qs
}
fn main() {
serve(use_query());
}
§#[header = "header-name"]
Value of the header.
use rweb::*;
#[get("/")]
fn ret_accept(#[header = "accept"] accept: String) -> String {
accept
}
fn main() {
serve(ret_accept());
}
§#[cookie = "cookie-name"]
Value of the header.
use rweb::*;
#[get("/")]
fn cookie(#[header = "sess"] sess_id: String) -> String {
sess_id
}
fn main() {
serve(cookie());
}
§#[filter = "path_to_fn"]
Calls function.
Note: If the callee returns ()
, you should use ()
as type. (Type
alias is not allowed)
use std::num::NonZeroU16;
use rweb::*;
use serde::Serialize;
#[derive(Serialize)]
struct Math {
op: String,
output: u16,
}
#[get("/math/{num}")]
fn math(num: u16, #[filter = "div_by"] denom: NonZeroU16) -> impl Reply {
rweb::reply::json(&Math {
op: format!("{} / {}", num, denom),
output: num / denom.get(),
})
}
fn div_by() -> impl Filter<Extract = (NonZeroU16,), Error = Rejection> +Copy
{ rweb::header::<u16>("div-by").and_then(|n: u16| async move {
if let Some(denom) = NonZeroU16::new(n) {
Ok(denom)
} else {
Err(reject::custom(DivideByZero))
}
})
}
#[derive(Debug)]
struct DivideByZero;
impl reject::Reject for DivideByZero {}
fn main() {
serve(math());
}
§#[data]
use futures::lock::Mutex;
use rweb::*;
use std::sync::Arc;
#[derive(Clone, Default)]
struct Db {
items: Arc<Mutex<Vec<String>>>,
}
#[get("/")]
async fn index(#[data] db: Db) -> Result<String, Rejection> {
let items = db.items.lock().await;
Ok(items.len().to_string())
}
fn main() {
let db = Default::default();
serve(index(db));
}
§FromRequest
use http::StatusCode;
use rweb::{filters::BoxedFilter, *};
impl FromRequest for User {
type Filter = BoxedFilter<(User,)>;
fn new() -> Self::Filter {
// In real world, you can use a header like Authorization
header::<String>("x-user-id").map(|id| User { id }).boxed()
}
}
#[derive(Schema)]
struct User {
id: String,
}
#[get("/")]
fn index(user: User) -> String {
user.id
}
fn main() {
serve(index());
}
§Guards
use rweb::*;
// This handler is invoked only if x-appengine-cron matches 1 (case insensitive).
#[get("/")]
#[header("X-AppEngine-Cron", "1")]
fn gae_cron() -> String {
String::new()
}
§#[router]
#[router]
can be used to group routes.
§#[data]
You can use #[data]
with a router.
use rweb::*;
#[derive(Default, Clone)]
struct Db {}
#[get("/use")]
fn use_db(#[data] _db: Db) -> String {
String::new()
}
#[router("/data", services(use_db))]
fn data_param(#[data] db: Db) {}
§Guard
use rweb::*;
#[get("/")]
fn admin_index() -> String {
String::new()
}
#[get("/users")]
fn admin_users() -> String {
String::new()
}
#[router("/admin", services(admin_index, admin_users))]
#[header("X-User-Admin", "1")]
fn admin() {}
Re-exports§
Modules§
- Built-in Filters
- A general purpose library of common HTTP types
- hyper
- Automatic openapi spec generator.
- Redirect requests to a new location.
- Rejections
- Reply to requests.
- Test utilities to test your filters.
Macros§
- Convenient way to chain multiple path filters together.
- Helper macro to chain multiple routes with .or(route()) between them.
Structs§
- Errors that can happen inside warp.
- Represents a request body with
www-url-form-encoded
content type. - Represents request body or response.
- Represents all query parameters.
- Rejection of a request by a
Filter
. - A Warp Server ready to filter requests.
- A Warp Server ready to filter requests over TLS.
Traits§
- Read bytes from a buffer.
- Composable request filters.
- A future represents an asynchronous computation obtained by use of
async
. - Types that can be converted into a
Response
. - A
Sink
is a value into which other values can be sent, asynchronously. - A stream of values produced asynchronously.
Functions§
- A filter that matches any route.
- Creates a
Filter
that requires a cookie by name. - Create a wrapping filter that exposes CORS behavior for a wrapped filter.
- Create a
Filter
that requires the request method to beDELETE
. - Create a
Filter
that requires the request method to beGET
. - Create a
Filter
that requires the request method to beHEAD
. - Create a
Filter
that tries to parse the specified header. - Create a wrapping filter with the specified
name
as thetarget
. - Extract the
Method
from the request. - Create a
Filter
that requires the request method to beOPTIONS
. - Create a
Filter
that requires the request method to bePATCH
. - Create an exact match path segment
Filter
. - Create a
Filter
that requires the request method to bePOST
. - Create a
Filter
that requires the request method to bePUT
. - Creates a
Filter
that decodes query parameters to the typeT
. - A simple
301
permanent redirect to a different location. - Rejects a request with
404 Not Found
. - Returns an empty
Reply
with status code200 OK
. - Create a
Server
with the providedFilter
. - Convert a
Filter
into aService
. - Create a wrapping filter that instruments every request with a custom
tracing
Span
provided by a function. - Function that receives a filter to be combined with pre and after filters
- Creates a Websocket Filter.
Attribute Macros§
- Creates a router. Useful for modularizing codes.
Derive Macros§
- Implements Entity for the type.