Macro preroll::main [−][src]
macro_rules! main { ($service_name:tt, $routes_fns:tt) => { ... }; ($service_name:tt, $state_setup:tt, $routes_fns:tt) => { ... }; ($service_name:tt, $state_setup:tt, $custom_setup:tt, $routes_fns:tt) => { ... }; }
Expand description
Begin here. A macro which constructs the equivalent of an async fn main() {}
.
Automatically pulls in setup for preroll’s default and optional features.
This macro takes the following arguments:
service_name
The constant service name, staticly set in the service’s code.
An &'static str
, e.g. "service-name"
.
state_setup
(optional)
This is where server state can be set.
An async fn setup_state() -> preroll::SetupResult<State>
, where State
is anything which can be thread-safe.
That is, the state must implement Send + Sync
, (usually automatically), and must have the 'static
lifetime (must be owned).
It is expected that State
is some arbitrary custom type used by your service. preroll
will wrap it in an Arc
so that it can be shared.
This function must be async
and must return a preroll::SetupResult
.
It is expected that setup could be anything and may need to await or error.
See tide::Server::with_state()
for more on Tide server state.
custom_setup
(optional) (advanced)
Advanced, custom setup with access to the full server struct. Prefer using routes_setup
whenever possible.
An async fn custom_setup(server: Server<Arc<State>>) -> SetupResult<Server<Arc<State>>>
, where State
is the type returned from setup_state
or else the unit ()
type.
routes_setup
(one or more)
This is where routes should be set.
A fn setup_routes(server: &mut tide::Server<Arc<State>>)
, where State
is the type returned from setup_state
or else the unit ()
type.
It is expected that only Tide route handlers are set in this function. It must not be async and must not error.
API Versioning
Any number of routes_setup
functions can be provided, by use of VariadicRoutes
, which will be API versioned as described below.
Usually this is done by putting the routes in a Tuple, similar to just adding more arguments but wrapping the routes arguments in parenthesis: (routes_v1, routes_v2)
.
Preroll route setup functions are automatically namespaced under /api/v{N}
where the {N}
is the position of the routes setup function in
preroll::main!
’s arguments, starting at 1
.
For example, preroll::main!("my-service", my_routes)
will have my_routes
mounted at /api/v1
.
See tide::Server::at()
for more on Tide server routing.
Basic Example
This will respond with "Hello World!"
when a GET request is made to $HOST:$PORT/api/v1/hello-world
.
use std::sync::Arc; use tide::{Request, Route}; struct AppState { greeting: &'static str, } type AppRequest = Request<Arc<AppState>>; async fn setup_app_state() -> preroll::SetupResult<AppState> { Ok(AppState { greeting: "Hello World!", }) } fn setup_routes(mut server: Route<'_, Arc<AppState>>) { server .at("hello-world") .get(|req: AppRequest| async move { Ok(req.state().greeting) }); } preroll::main!("hello-world", setup_app_state, setup_routes);
Full Example
With custom middleware and multiple api versions.
use std::sync::Arc; use preroll::SetupResult; use tide::{Request, Route, Server}; pub struct AppState { greeting: &'static str, } type AppRequest = Request<Arc<AppState>>; async fn setup_app_state() -> preroll::SetupResult<AppState> { Ok(AppState { greeting: "Hello World!", }) } pub async fn setup_custom( server: Server<Arc<AppState>> ) -> SetupResult<Server<Arc<AppState>>> { // Adjust `server` in whichever ways neccessary Ok(server) } fn setup_routes_v1(mut server: Route<'_, Arc<AppState>>) { server .at("hello-world") .get(|req: AppRequest| async move { Ok(req.state().greeting) }); } fn setup_routes_v2(mut server: Route<'_, Arc<AppState>>) { server .at("hello-world") .get(|req: AppRequest| async move { Ok("Hello from v2!") }); } preroll::main!( "hello-world", setup_app_state, setup_custom, (setup_routes_v1, setup_routes_v2) );