Crate rweb[][src]

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());
}

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

pub use warp;
pub use self::docs::*;
pub use self::routes::*;

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.

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 be DELETE.

Create a Filter that requires the request method to be GET.

Create a Filter that requires the request method to be HEAD.

Create a Filter that tries to parse the specified header.

Create a wrapping filter with the specified name as the target.

Extract the Method from the request.

Create a Filter that requires the request method to be OPTIONS.

Create a Filter that requires the request method to be PATCH.

Create an exact match path segment Filter.

Create a Filter that requires the request method to be POST.

Create a Filter that requires the request method to be PUT.

Creates a Filter that decodes query parameters to the type T.

A simple 301 permanent redirect to a different location.

Rejects a request with 404 Not Found.

Returns an empty Reply with status code 200 OK.

Create a Server with the provided Filter.

Convert a Filter into a Service.

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.