[][src]Macro vial::routes

macro_rules! routes {
    (
        $(#![filter($($all_filter:ident),+)])*

        $(
            $(#[filter($($action_filter:ident),+)])*
            $method:ident $path:expr => $body:expr;)*
        ) => { ... };
}

The vial::routes! macro, they say, is half of the battle, with the other 50% being a toss up between "knowledge" and the vial::run! macro you use to start your app.

In Vial, routes are defined within the routes! macro in this format:

HTTP_METHOD ROUTE_PATTERN => ACTION;

The order in which routes are written matters - routes written first will be checked for matches first, meaning you can declare many routes that point to "/", but only the first one defined will ever match.

HTTP Methods

HTTP_METHOD should be an all caps HTTP method. It will get converted into a Method enum and can be any one of:

  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • PATCH
  • OPTIONS
  • TRACE

Route Patterns

ROUTE_PATTERN can be an exact match, such as "/user" or "/v2/search.php3", or can include a named URL parameter:

  1. "/:name" — This will match anything except paths with / or . in them.
  2. "/:name.md" — Use this format to match on a specific file extension.
  3. "/*name" — This will match everything, including / and .

In the three examples above, calling request.arg("name") in an Action will return Some(&str).

Note that you can have multiple parameters in the same route, as long as the wildcard pattern occurs last:

vial::routes! {
    GET "/:category/:id/*name" => |req| format!(
        "<p>Category: {}</p>
        <p>ID: {}</p>
        <p>Name: {}</p>",
        req.arg("category").unwrap_or("None"),
        req.arg("id").unwrap_or("None"),
        req.arg("name").unwrap_or("None"),
    );
}

fn main() {
    vial::run!();
}

Actions

Actions are what routes actually route to.

They are functions or closures take a Request and return a Responder of some kind.

use vial::prelude::*;

routes! {
    GET "/info" => |req| format!(
        "<p>Name: {}</p>", req.query("name").unwrap_or("None")
    );
    GET "/" => index;
}

fn index(req: Request) -> impl Responder {
    "<form method='GET'>
        <p>Enter your name: <input type='text' name='name'/></p>
        <input type='submit'/>
    </form>"
}

fn main() {
    run!();
}

Returning impl Responder is easy - Responder is a Vial trait that defines a single conversion method that returns a Response:

pub trait Responder {
    fn to_response(self) -> Response;
}

These types implement Responder by default:

  • &str
  • String
  • usize - Empty response with this number as the status code.
  • Option<impl Responder> - 404 on None
  • Result<impl Responder, Error> - 500 on Error