[][src]Crate rweb

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

#[herader("content-type", "applcation/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::routes::*;

Modules

filters

Built-in Filters

http

A general purpose library of common HTTP types

hyper

hyper

openapi

Automatic openapi spec generator.

redirect

Redirect requests to a new location.

reject

Rejections

reply

Reply to requests.

routes
test

Test utilities to test your filters.

Macros

path

Convenient way to chain multiple path filters together.

routes

Helper macro to chain multiple routes with .or(route()) between them.

Structs

Error

Errors that can happen inside warp.

Form

Represents a request body with www-url-form-encoded content type.

Json

Represents request body or response.

Query

Represents all query parameters.

Rejection

Rejection of a request by a Filter.

Server

A Warp Server ready to filter requests.

Traits

Buf

Read bytes from a buffer.

Filter

Composable request filters.

FromRequest
Future

A future represents an asynchronous computation.

Reply

Types that can be converted into a Response.

Sink

A Sink is a value into which other values can be sent, asynchronously.

Stream

A stream of values produced asynchronously.

Functions

any

A filter that matches any route.

cookie

Creates a Filter that requires a cookie by name.

cors

Create a wrapping filter that exposes CORS behavior for a wrapped filter.

delete

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

get

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

head

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

header

Create a Filter that tries to parse the specified header.

log

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

method

Extract the Method from the request.

options

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

patch

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

path

Create an exact match path segment Filter.

post

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

put

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

query

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

redirect

A simple 301 redirect to a different location.

reject

Rejects a request with 404 Not Found.

reply

Returns an empty Reply with status code 200 OK.

serve

Create a Server with the provided Filter.

service

Convert a Filter into a Service.

ws

Creates a Websocket Filter.

Attribute Macros

delete
get
head
options
patch
post
put
router

Creates a router. Useful for modularizing codes.

Derive Macros

Schema

Implements Entity for the type.