mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
example of middleware that can run before and/or after server fn
This commit is contained in:
parent
22b4537f27
commit
5065bed594
3 changed files with 38 additions and 4 deletions
|
@ -30,6 +30,7 @@ toml = "0.8.8"
|
|||
web-sys = { version = "0.3.67", features = ["FileList", "File"] }
|
||||
strum = { version = "0.25.0", features = ["strum_macros", "derive"] }
|
||||
notify = { version = "6.1.1", optional = true }
|
||||
pin-project-lite = "0.2.13"
|
||||
|
||||
[features]
|
||||
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
|
||||
|
|
|
@ -242,6 +242,7 @@ pub fn WithActionForm() -> impl IntoView {
|
|||
// In this case, any `tower::Layer` that takes services of `Request<Body>` will work
|
||||
#[middleware(crate::middleware::LoggingLayer)]
|
||||
pub async fn length_of_input(input: String) -> Result<usize, ServerFnError> {
|
||||
println!("2. Running server function.");
|
||||
// insert a simulated wait
|
||||
tokio::time::sleep(std::time::Duration::from_millis(250)).await;
|
||||
Ok(input.len())
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
use axum::body::Body;
|
||||
use http::Request;
|
||||
use std::task::{Context, Poll};
|
||||
use pin_project_lite::pin_project;
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tower::{Layer, Service};
|
||||
|
||||
pub struct LoggingLayer;
|
||||
|
@ -23,7 +28,7 @@ where
|
|||
{
|
||||
type Response = T::Response;
|
||||
type Error = T::Error;
|
||||
type Future = T::Future;
|
||||
type Future = LoggingServiceFuture<T::Future>;
|
||||
|
||||
fn poll_ready(
|
||||
&mut self,
|
||||
|
@ -33,8 +38,35 @@ where
|
|||
}
|
||||
|
||||
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
||||
println!("Running my middleware!");
|
||||
println!("1. Running my middleware!");
|
||||
|
||||
self.inner.call(req)
|
||||
LoggingServiceFuture {
|
||||
inner: self.inner.call(req),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin_project! {
|
||||
pub struct LoggingServiceFuture<T> {
|
||||
#[pin]
|
||||
inner: T,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Future for LoggingServiceFuture<T>
|
||||
where
|
||||
T: Future,
|
||||
{
|
||||
type Output = T::Output;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.project();
|
||||
match this.inner.poll(cx) {
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(output) => {
|
||||
println!("3. Running my middleware!");
|
||||
Poll::Ready(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue