Struct rocket::Rocket [−][src]
pub struct Rocket<P: Phase>(_);
Expand description
The application server itself.
Phases
An instance of Rocket
represents a web server and its state. It progresses
through three statically-enforced phases into orbit: build, ignite, orbit.
Build
All application and server configuration occurs during the Build
phase.
This includes setting configuration options, mounting/registering
routes/catchers, managing state, and attaching fairings. This is the only
phase in which an instance can be modified. To finalize changes, an instance
is ignited via Rocket::ignite()
, progressing it into the ignite phase,
or directly launched into orbit with Rocket::launch()
which progress the
instance through ignite into orbit.
Ignite
An instance in the Ignite
phase is in its final configuration, available
via Rocket::config()
. Barring user-supplied iterior mutation,
application state is guaranteed to remain unchanged beyond this point. An
instance in the ignite phase can be launched into orbit to serve requests
via Rocket::launch()
.
Orbit
An instance in the Orbit
phase represents a running application,
actively serving requests.
Launching
Manual Launching
To launch an instance of Rocket
, it must progress through all three
phases. To progress into the ignite or launch phases, a tokio async
runtime is required. The #[main]
attribute initializes a
Rocket-specific tokio runtime and runs the attributed async fn
inside of
it:
#[rocket::main] async fn main() -> Result<(), rocket::Error> { rocket::build() .ignite().await? .launch().await }
Note that Rocket::launch()
automatically progresses an instance of
Rocket
from any phase into orbit:
#[rocket::main] async fn main() -> Result<(), rocket::Error> { rocket::build().launch().await }
Automatic Launching
Manually progressing an instance of Rocket though its phases is only
necessary when either an instance’s finalized state is to be inspected (in
the ignite phase) or the instance is expected to deorbit due to
Rocket::shutdown()
. In the more common case when neither is required,
the #[launch]
attribute can be used. When applied to a
function that returns a Rocket<Build>
, it automatically initializes an
async
runtime and launches the function’s returned instance:
use rocket::{Rocket, Build}; #[launch] fn rocket() -> Rocket<Build> { rocket::build() }
To avoid needing to import any items in the common case, the launch
attribute will infer a return type written as _
as Rocket<Build>
:
#[launch] fn rocket() -> _ { rocket::build() }
Implementations
Create a new Rocket
application using the default configuration
provider, Config::figment()
.
This method is typically called through the
rocket::build()
alias.
Examples
#[launch] fn rocket() -> _ { rocket::build() }
Creates a new Rocket
application using the supplied configuration
provider.
This method is typically called through the
rocket::custom()
alias.
Example
use rocket::figment::{Figment, providers::{Toml, Env, Format}}; #[launch] fn rocket() -> _ { let figment = Figment::from(rocket::Config::default()) .merge(Toml::file("MyApp.toml").nested()) .merge(Env::prefixed("MY_APP_").global()); rocket::custom(figment) }
Sets the configuration provider in self
to provider
.
A Figment
generated from the current provider
can always be
retrieved via Rocket::figment()
. However, because the provider can
be changed at any point prior to ignition, a Config
can only be
retrieved in the ignite or orbit phases, or by manually extracing one
from a particular figment.
Example
use rocket::Config; let config = Config { port: 7777, address: Ipv4Addr::new(18, 127, 0, 1).into(), temp_dir: PathBuf::from("/tmp/config-example"), ..Config::debug_default() }; let rocket = rocket::custom(&config).ignite().await?; assert_eq!(rocket.config().port, 7777); assert_eq!(rocket.config().address, Ipv4Addr::new(18, 127, 0, 1)); assert_eq!(rocket.config().temp_dir, Path::new("/tmp/config-example")); // Create a new figment which modifies _some_ keys the existing figment: let figment = rocket.figment().clone() .merge((Config::PORT, 8888)) .merge((Config::ADDRESS, "171.64.200.10")); let rocket = rocket::custom(&config) .configure(figment) .ignite().await?; assert_eq!(rocket.config().port, 8888); assert_eq!(rocket.config().address, Ipv4Addr::new(171, 64, 200, 10)); assert_eq!(rocket.config().temp_dir, Path::new("/tmp/config-example"));
Mounts all of the routes in the supplied vector at the given base
path. Mounting a route with path path
at path base
makes the route
available at base/path
.
Panics
Panics if either:
-
the
base
mount point is not a valid static path: a valid origin URI without dynamic parameters. -
any route’s URI is not a valid origin URI.
Note: This kind of panic is guaranteed not to occur if the routes were generated using Rocket’s code generation.
Examples
Use the routes!
macro to mount routes created using the code
generation facilities. Requests to the /hello/world
URI will be
dispatched to the hi
route.
#[get("/world")] fn hi() -> &'static str { "Hello!" } #[launch] fn rocket() -> _ { rocket::build().mount("/hello", routes![hi]) }
Manually create a route named hi
at path "/world"
mounted at base
"/hello"
. Requests to the /hello/world
URI will be dispatched to the
hi
route.
use rocket::{Request, Route, Data, route}; use rocket::http::Method; fn hi<'r>(req: &'r Request, _: Data<'r>) -> route::BoxFuture<'r> { route::Outcome::from(req, "Hello!").pin() } #[launch] fn rocket() -> _ { let hi_route = Route::new(Method::Get, "/world", hi); rocket::build().mount("/hello", vec![hi_route]) }
Registers all of the catchers in the supplied vector, scoped to base
.
Panics
Panics if base
is not a valid static path: a valid origin URI without
dynamic parameters.
Examples
use rocket::Request; #[catch(500)] fn internal_error() -> &'static str { "Whoops! Looks like we messed up." } #[catch(400)] fn not_found(req: &Request) -> String { format!("I couldn't find '{}'. Try something else?", req.uri()) } #[launch] fn rocket() -> _ { rocket::build().register("/", catchers![internal_error, not_found]) }
Add state
to the state managed by this instance of Rocket.
This method can be called any number of times as long as each call
refers to a different T
.
Managed state can be retrieved by any request handler via the
State
request guard. In particular, if a value of type T
is managed by Rocket, adding State<T>
to the list of arguments in a
request handler instructs Rocket to retrieve the managed value.
Panics
Panics if state of type T
is already being managed.
Example
use rocket::State; struct MyInt(isize); struct MyString(String); #[get("/int")] fn int(state: &State<MyInt>) -> String { format!("The stateful int is: {}", state.0) } #[get("/string")] fn string(state: &State<MyString>) -> &str { &state.0 } #[launch] fn rocket() -> _ { rocket::build() .manage(MyInt(10)) .manage(MyString("Hello, managed state!".to_string())) .mount("/", routes![int, string]) }
Attaches a fairing to this instance of Rocket. No fairings are eagerly excuted; fairings are executed at their appropriate time.
If the attached fairing is fungible and a fairing of the same name already exists, this fairing replaces it.
Example
use rocket::Rocket; use rocket::fairing::AdHoc; #[launch] fn rocket() -> _ { rocket::build() .attach(AdHoc::on_liftoff("Liftoff Message", |_| Box::pin(async { println!("We have liftoff!"); }))) }
Returns a Future
that transitions this instance of Rocket
into the
ignite phase.
When await
ed, the future runs all ignite fairings in serial,
attach order, and verifies that self
represents a
valid instance of Rocket
ready for launch. This means that:
- All ignite fairings succeeded.
- A valid
Config
was extracted fromRocket::figment()
. - If
secrets
are enabled, the extractedConfig
contains a safe secret key. - There are no
Route
orCatcher
collisions. - No
Sentinel
triggered an abort.
If any of these conditions fail to be met, a respective Error
is
returned.
Example
use rocket::fairing::AdHoc; #[rocket::main] async fn main() -> Result<(), rocket::Error> { let rocket = rocket::build() .attach(AdHoc::on_ignite("Manage State", |rocket| async move { rocket.manage(String::from("managed string")) })); // No fairings are run until ignition occurs. assert!(rocket.state::<String>().is_none()); let rocket = rocket.ignite().await?; assert_eq!(rocket.state::<String>().unwrap(), "managed string"); Ok(()) }
Returns the finalized, active configuration. This is guaranteed to remain stable through ignition and into orbit.
Example
#[rocket::main] async fn main() -> Result<(), rocket::Error> { let rocket = rocket::build().ignite().await?; let config = rocket.config(); Ok(()) }
Returns a handle which can be used to trigger a shutdown and detect a triggered shutdown.
A completed graceful shutdown resolves the future returned by
Rocket::launch()
. If Shutdown::notify()
is called before an
instance is launched, it will be immediately shutdown after liftoff. See
Shutdown
and config::Shutdown
for
details on graceful shutdown.
Example
use rocket::tokio::{self, time}; #[rocket::main] async fn main() -> Result<(), rocket::Error> { let rocket = rocket::build().ignite().await?; let shutdown = rocket.shutdown(); tokio::spawn(async move { time::sleep(time::Duration::from_secs(5)).await; shutdown.notify(); }); // The `launch()` future resolves after ~5 seconds. let result = rocket.launch().await; assert!(result.is_ok()); Ok(()) }
Returns the finalized, active configuration. This is guaranteed to
remain stable after Rocket::ignite()
, through ignition and into
orbit.
Example
use rocket::fairing::AdHoc; #[launch] fn rocket() -> _ { rocket::build() .attach(AdHoc::on_liftoff("Config", |rocket| Box::pin(async move { println!("Rocket launch config: {:?}", rocket.config()); }))) }
Returns a handle which can be used to trigger a shutdown and detect a triggered shutdown.
A completed graceful shutdown resolves the future returned by
Rocket::launch()
. See Shutdown
and
config::Shutdown
for details on graceful
shutdown.
Example
use rocket::tokio::{self, time}; use rocket::fairing::AdHoc; #[launch] fn rocket() -> _ { rocket::build() .attach(AdHoc::on_liftoff("Shutdown", |rocket| Box::pin(async move { let shutdown = rocket.shutdown(); tokio::spawn(async move { time::sleep(time::Duration::from_secs(5)).await; shutdown.notify(); }); }))) }
Returns an iterator over all of the routes mounted on this instance of Rocket. The order is unspecified.
Example
use rocket::Rocket; use rocket::fairing::AdHoc; #[get("/hello")] fn hello() -> &'static str { "Hello, world!" } let rocket = rocket::build() .mount("/", routes![hello]) .mount("/hi", routes![hello]); assert_eq!(rocket.routes().count(), 2); assert!(rocket.routes().any(|r| r.uri == "/hello")); assert!(rocket.routes().any(|r| r.uri == "/hi/hello"));
Returns an iterator over all of the catchers registered on this instance of Rocket. The order is unspecified.
Example
use rocket::Rocket; use rocket::fairing::AdHoc; #[catch(404)] fn not_found() -> &'static str { "Nothing here, sorry!" } #[catch(500)] fn just_500() -> &'static str { "Whoops!?" } #[catch(default)] fn some_default() -> &'static str { "Everything else." } let rocket = rocket::build() .register("/foo", catchers![not_found]) .register("/", catchers![just_500, some_default]); assert_eq!(rocket.catchers().count(), 3); assert!(rocket.catchers().any(|c| c.code == Some(404) && c.base == "/foo")); assert!(rocket.catchers().any(|c| c.code == Some(500) && c.base == "/")); assert!(rocket.catchers().any(|c| c.code == None && c.base == "/"));
Returns Some
of the managed state value for the type T
if it is
being managed by self
. Otherwise, returns None
.
Example
#[derive(PartialEq, Debug)] struct MyState(&'static str); let rocket = rocket::build().manage(MyState("hello!")); assert_eq!(rocket.state::<MyState>().unwrap(), &MyState("hello!"));
Returns the figment derived from the configuration provider set for
self
. To extract a typed config, prefer to use
AdHoc::config()
.
Example
let rocket = rocket::build(); let figment = rocket.figment();
Returns a Future
that transitions this instance of Rocket
from any
phase into the orbit phase. When await
ed, the future drives the
server forward, listening for and dispatching requests to mounted routes
and catchers.
In addition to all of the processes that occur during
ignition, a successful launch results in liftoff
fairings being executed after binding to any respective network
interfaces but before serving the first request. Liftoff fairings are
run concurrently; resolution of all fairings is await
ed before
resuming request serving.
The Future
resolves as an Err
if any of the following occur:
- there is an error igniting; see
Rocket::ignite()
. - there is an I/O error starting the server.
- an unrecoverable, system-level error occurs while running.
The Future
resolves as an Ok
if any of the following occur:
- graceful shutdown via
Shutdown::notify()
completes.
The Future
does not resolve otherwise.
Error
If there is a problem starting the application, an Error
is
returned. Note that a value of type Error
panics if dropped without
first being inspected. See the Error
documentation for more
information.
Example
#[rocket::main] async fn main() { let result = rocket::build().launch().await; // this is reachable only after `Shutdown::notify()` or `Ctrl+C`. println!("Rocket: deorbit."); }
Trait Implementations
Auto Trait Implementations
impl<P> RefUnwindSafe for Rocket<P> where
<P as Phase>::State: RefUnwindSafe,
impl<P> UnwindSafe for Rocket<P> where
<P as Phase>::State: UnwindSafe,