Initializers
Initializers are a way to encapsulate a piece of infrastructure "wiring" that you need to do in your app. You put initializers in src/initializers/
.
Writing initializers
Currently, an initializer is anything that implements the Initializer
trait:
// implement this and place your code in `src/initializers/`
Example: Integrating Axum Session
You might want to add sessions to your app using axum-session
. Also, you might want to share that piece of functionality between your own projects, or grab that piece of code from someone else.
You can achieve this reuse easily, if you code the integration as an initializer:
// place this in `src/initializers/axum_session.rs`
And now your app structure looks like this:
src/
bin/
controllers/
:
:
initializers/ <--- a new folder
mod.rs <--- a new module
axum_session.rs <--- your new initializer
:
:
app.rs <--- register initializers here
Using initializers
After you've implemented your own initializer, you should implement the initializers(..)
hook in your src/app.rs
and provide a Vec of your initializers:
// in src/app.rs
Loco will now run your initializer stack in the correct places during the app boot process.
What other things you can do?
Right now initializers contain two integration points:
before_run
- happens before running the app -- this is a pure "initialization" type of a hook. You can send web hooks, metric points, do cleanups, pre-flight checks, etc.after_routes
- happens after routes have been added. You have access to the Axum router and its powerful layering integration points, this is where you will spend most of your time.
Compared to Rails initializers
Rails initializers, are regular scripts that run once -- for initialization and have access to everything. They get their power from being able to access a "live" Rails app, modify it as a global instance.
In Loco, accessing a global instance and mutating it is not possible in Rust (for a good reason!), and so we offer two integration points which are explicit and safe:
- Pure initialization (without any influence on a configured app)
- Integration with a running app (via Axum router)
Rails initializers need ordering and modification. Meaning, a user should be certain that they run in a specific order (or re-order them), and a user is able to remove initializers that other people set before them.
In Loco, we circumvent this complexity by making the user provide a full vec of initializers. Vecs are ordered, and there are no implicit initializers.
The global logger initializer
Some developers would like to customize their logging stack. In Loco this involves setting up tracing and tracing subscribers.
Because at the moment tracing does not allow for re-initialization, or modification of an in-flight tracing stack, you only get one chance to initialize and registr a global tracing stack.
This is why we added a new App level hook, called init_logger
, which you can use to provide your own logging stack initialization.
// in src/app.rs
After you've set up your own logger, return Ok(true)
to signal that you took over initialization.