mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
feat: add From for RequestParts into Parts for Axum and add an option to ge… (#931)
This commit is contained in:
parent
fa2e2248d3
commit
6c3381ce52
4 changed files with 87 additions and 9 deletions
|
@ -1,12 +1,15 @@
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main(){
|
async fn main() {
|
||||||
|
use axum::{
|
||||||
|
extract::{Extension, Path},
|
||||||
|
routing::{get, post},
|
||||||
|
Router,
|
||||||
|
};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||||
use axum::{extract::{Extension, Path}, Router, routing::{get, post}};
|
use ssr_modes_axum::{app::*, fallback::file_and_error_handler};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ssr_modes_axum::fallback::file_and_error_handler;
|
|
||||||
use ssr_modes_axum::app::*;
|
|
||||||
|
|
||||||
let conf = get_configuration(None).await.unwrap();
|
let conf = get_configuration(None).await.unwrap();
|
||||||
let addr = conf.leptos_options.site_addr;
|
let addr = conf.leptos_options.site_addr;
|
||||||
|
@ -19,7 +22,11 @@ async fn main(){
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/api/*fn_name", post(leptos_axum::handle_server_fns))
|
.route("/api/*fn_name", post(leptos_axum::handle_server_fns))
|
||||||
.leptos_routes(leptos_options.clone(), routes, |cx| view! { cx, <App/> })
|
.leptos_routes(
|
||||||
|
leptos_options.clone(),
|
||||||
|
routes,
|
||||||
|
|cx| view! { cx, <App/> },
|
||||||
|
)
|
||||||
.fallback(file_and_error_handler)
|
.fallback(file_and_error_handler)
|
||||||
.layer(Extension(Arc::new(leptos_options)));
|
.layer(Extension(Arc::new(leptos_options)));
|
||||||
|
|
||||||
|
|
|
@ -905,6 +905,20 @@ async fn render_app_async_helper(
|
||||||
pub fn generate_route_list<IV>(
|
pub fn generate_route_list<IV>(
|
||||||
app_fn: impl FnOnce(leptos::Scope) -> IV + 'static,
|
app_fn: impl FnOnce(leptos::Scope) -> IV + 'static,
|
||||||
) -> Vec<RouteListing>
|
) -> Vec<RouteListing>
|
||||||
|
where
|
||||||
|
IV: IntoView + 'static,
|
||||||
|
{
|
||||||
|
generate_route_list_with_exclusions(app_fn, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a list of all routes defined in Leptos's Router in your app. We can then use this to automatically
|
||||||
|
/// create routes in Actix's App without having to use wildcard matching or fallbacks. Takes in your root app Element
|
||||||
|
/// as an argument so it can walk you app tree. This version is tailored to generated Actix compatible paths. Adding excluded_routes
|
||||||
|
/// to this function will stop `.leptos_routes()` from generating a route for it, allowing a custom handler. These need to be in Actix path format
|
||||||
|
pub fn generate_route_list_with_exclusions<IV>(
|
||||||
|
app_fn: impl FnOnce(leptos::Scope) -> IV + 'static,
|
||||||
|
excluded_routes: Option<Vec<String>>,
|
||||||
|
) -> Vec<RouteListing>
|
||||||
where
|
where
|
||||||
IV: IntoView + 'static,
|
IV: IntoView + 'static,
|
||||||
{
|
{
|
||||||
|
@ -932,7 +946,7 @@ where
|
||||||
// Match `:some_word` but only capture `some_word` in the groups to replace with `{some_word}`
|
// Match `:some_word` but only capture `some_word` in the groups to replace with `{some_word}`
|
||||||
let capture_re = Regex::new(r":((?:[^.,/]+)+)[^/]?").unwrap();
|
let capture_re = Regex::new(r":((?:[^.,/]+)+)[^/]?").unwrap();
|
||||||
|
|
||||||
let routes = routes
|
let mut routes = routes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|listing| {
|
.map(|listing| {
|
||||||
let path = wildcard_re
|
let path = wildcard_re
|
||||||
|
@ -946,6 +960,10 @@ where
|
||||||
if routes.is_empty() {
|
if routes.is_empty() {
|
||||||
vec![RouteListing::new("/", Default::default(), [Method::Get])]
|
vec![RouteListing::new("/", Default::default(), [Method::Get])]
|
||||||
} else {
|
} else {
|
||||||
|
// Routes to exclude from auto generation
|
||||||
|
if let Some(excluded_routes) = excluded_routes {
|
||||||
|
routes.retain(|p| !excluded_routes.iter().any(|e| e == p.path()))
|
||||||
|
}
|
||||||
routes
|
routes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,10 @@ use futures::{
|
||||||
channel::mpsc::{Receiver, Sender},
|
channel::mpsc::{Receiver, Sender},
|
||||||
Future, SinkExt, Stream, StreamExt,
|
Future, SinkExt, Stream, StreamExt,
|
||||||
};
|
};
|
||||||
use http::{header, method::Method, uri::Uri, version::Version, Response};
|
use http::{
|
||||||
|
header, method::Method, request::Parts, uri::Uri, version::Version,
|
||||||
|
Response,
|
||||||
|
};
|
||||||
use hyper::body;
|
use hyper::body;
|
||||||
use leptos::{
|
use leptos::{
|
||||||
leptos_server::{server_fn_by_path, Payload},
|
leptos_server::{server_fn_by_path, Payload},
|
||||||
|
@ -46,6 +49,21 @@ pub struct RequestParts {
|
||||||
pub headers: HeaderMap<HeaderValue>,
|
pub headers: HeaderMap<HeaderValue>,
|
||||||
pub body: Bytes,
|
pub body: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert http::Parts to RequestParts(and vice versa). Body and Extensions will
|
||||||
|
/// be lost in the conversion
|
||||||
|
impl From<Parts> for RequestParts {
|
||||||
|
fn from(parts: Parts) -> Self {
|
||||||
|
Self {
|
||||||
|
version: parts.version,
|
||||||
|
method: parts.method,
|
||||||
|
uri: parts.uri,
|
||||||
|
headers: parts.headers,
|
||||||
|
body: Bytes::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This struct lets you define headers and override the status of the Response from an Element or a Server Function
|
/// This struct lets you define headers and override the status of the Response from an Element or a Server Function
|
||||||
/// Typically contained inside of a ResponseOptions. Setting this is useful for cookies and custom responses.
|
/// Typically contained inside of a ResponseOptions. Setting this is useful for cookies and custom responses.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
@ -1003,6 +1021,21 @@ where
|
||||||
pub async fn generate_route_list<IV>(
|
pub async fn generate_route_list<IV>(
|
||||||
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
||||||
) -> Vec<RouteListing>
|
) -> Vec<RouteListing>
|
||||||
|
where
|
||||||
|
IV: IntoView + 'static,
|
||||||
|
{
|
||||||
|
generate_route_list_with_exclusions(app_fn, None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a list of all routes defined in Leptos's Router in your app. We can then use this to automatically
|
||||||
|
/// create routes in Axum's Router without having to use wildcard matching or fallbacks. Takes in your root app Element
|
||||||
|
/// as an argument so it can walk you app tree. This version is tailored to generate Axum compatible paths. Adding excluded_routes
|
||||||
|
/// to this function will stop `.leptos_routes()` from generating a route for it, allowing a custom handler. These need to be in Axum path format
|
||||||
|
#[tracing::instrument(level = "trace", fields(error), skip_all)]
|
||||||
|
pub async fn generate_route_list_with_exclusions<IV>(
|
||||||
|
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
||||||
|
excluded_routes: Option<Vec<String>>,
|
||||||
|
) -> Vec<RouteListing>
|
||||||
where
|
where
|
||||||
IV: IntoView + 'static,
|
IV: IntoView + 'static,
|
||||||
{
|
{
|
||||||
|
@ -1029,7 +1062,7 @@ where
|
||||||
|
|
||||||
let routes = routes.0.read().to_owned();
|
let routes = routes.0.read().to_owned();
|
||||||
// Axum's Router defines Root routes as "/" not ""
|
// Axum's Router defines Root routes as "/" not ""
|
||||||
let routes = routes
|
let mut routes = routes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|listing| {
|
.map(|listing| {
|
||||||
let path = listing.path();
|
let path = listing.path();
|
||||||
|
@ -1052,6 +1085,10 @@ where
|
||||||
[leptos_router::Method::Get],
|
[leptos_router::Method::Get],
|
||||||
)]
|
)]
|
||||||
} else {
|
} else {
|
||||||
|
// Routes to exclude from auto generation
|
||||||
|
if let Some(excluded_routes) = excluded_routes {
|
||||||
|
routes.retain(|p| !excluded_routes.iter().any(|e| e == p.path()))
|
||||||
|
}
|
||||||
routes
|
routes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -947,6 +947,19 @@ where
|
||||||
pub async fn generate_route_list<IV>(
|
pub async fn generate_route_list<IV>(
|
||||||
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
||||||
) -> Vec<RouteListing>
|
) -> Vec<RouteListing>
|
||||||
|
where
|
||||||
|
IV: IntoView + 'static,
|
||||||
|
{
|
||||||
|
generate_route_list_with_exclusions(app_fn, None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a list of all routes defined in Leptos's Router in your app. We can then use this to automatically
|
||||||
|
/// create routes in Viz's Router without having to use wildcard matching or fallbacks. Takes in your root app Element
|
||||||
|
/// as an argument so it can walk you app tree. This version is tailored to generate Viz compatible paths.
|
||||||
|
pub async fn generate_route_list_with_exclusions<IV>(
|
||||||
|
app_fn: impl FnOnce(Scope) -> IV + 'static,
|
||||||
|
excluded_routes: Option<Vec<String>>,
|
||||||
|
) -> Vec<RouteListing>
|
||||||
where
|
where
|
||||||
IV: IntoView + 'static,
|
IV: IntoView + 'static,
|
||||||
{
|
{
|
||||||
|
@ -973,7 +986,7 @@ where
|
||||||
|
|
||||||
let routes = routes.0.read().to_owned();
|
let routes = routes.0.read().to_owned();
|
||||||
// Viz's Router defines Root routes as "/" not ""
|
// Viz's Router defines Root routes as "/" not ""
|
||||||
let routes = routes
|
let mut routes = routes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|listing| {
|
.map(|listing| {
|
||||||
let path = listing.path();
|
let path = listing.path();
|
||||||
|
@ -996,6 +1009,9 @@ where
|
||||||
[leptos_router::Method::Get],
|
[leptos_router::Method::Get],
|
||||||
)]
|
)]
|
||||||
} else {
|
} else {
|
||||||
|
if let Some(excluded_routes) = excluded_routes {
|
||||||
|
routes.retain(|p| !excluded_routes.iter().any(|e| e == p.path()))
|
||||||
|
}
|
||||||
routes
|
routes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue