Axum with Leptos: how do I get AppState in [server] Macro?

1.1k views Asked by At

I try to work with axum and leptos on a fullstack app

I am trying to use a server shared resource with SSR leptos handlers, which usually would be an AppState struct added to the router with with_state()

After studying multiple examples, I am wondering: how do I deal with the AppState, that I usually load with "State" in an axum handler, when I use a leptos #[server]-Macro based handler function?

#[server(Something, "/api")]
pub async fn something(cx: Scope, arg: MyStruct, state: State<AppState>) -> Result<String, ServerFnError> { ... }

will not work.

1

There are 1 answers

0
g4borg On BEST ANSWER

After looking further I finally managed to make it work, the hint was in the docs, which lead me to this piece of code:

Example of using custom routes

In essence,

  1. define a custom route-handler for leptos_routes_with_handler which calls leptos_axum::render_app_to_stream_with_context and provides required states there in the context
  2. define a server_fn_handler that calls handle_server_fn_with_context, yet again providing the states yet again in the context
  3. define some kind of extractor function that you can use from your #[server] function, that uses use_context::T to extract the type from the Scope.

I personally used the approach to define a function on a state I want to extract:

impl MyState {
    pub fn from_cx(cx: Scope) -> Result<MyState, ServerFnError> {
                use_context::<MyState>(cx)
                    .ok_or_else(|| ServerFnError::ServerError("My State missing.".into()))
    }
}

so I can retrieve it inside my

#[server(Something, "/api")]
pub async fn something(cx: Scope, arg: MyStruct) -> Result<String, ServerFnError> {
   let my_state = MyState::from_cx(cx)?;
}

but the example code in the repo uses a simple function (see in todo.rs), and uses two substates of the AppState, the AuthSession and the SqlitePool, that are delivered via Scope.