update server functions commit
This commit is contained in:
1 parent
7193453fe0
commit
0726a7b08f
8 files changed
+138
-58
No files matched your search
@@ -47,9 +47,12 @@
|
||||
//!
|
||||
//! ```
|
||||
|
||||
use std::{error::Error, sync::Arc};
|
||||
use crate::{
|
||||
prelude::*, render::SSRState, serve_config::ServeConfig, server_fn::DioxusServerFnRegistry,
|
||||
};
|
||||
|
||||
use server_fn::{Payload, ServerFunctionRegistry};
|
||||
use server_fn::{Encoding, Payload, ServerFunctionRegistry};
|
||||
use std::error::Error;
|
||||
use tokio::task::spawn_blocking;
|
||||
use warp::{
|
||||
filters::BoxedFilter,
|
||||
@@ -58,13 +61,6 @@ use warp::{
|
||||
path, Filter, Reply,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
prelude::DioxusServerContext,
|
||||
render::SSRState,
|
||||
serve_config::ServeConfig,
|
||||
server_fn::{DioxusServerFnRegistry, ServerFnTraitObj},
|
||||
};
|
||||
|
||||
/// Registers server functions with a custom handler function. This allows you to pass custom context to your server functions by generating a [`DioxusServerContext`] from the request.
|
||||
///
|
||||
/// # Example
|
||||
@@ -94,7 +90,7 @@ pub fn register_server_fns_with_handler<H, F, R>(
|
||||
mut handler: H,
|
||||
) -> BoxedFilter<(R,)>
|
||||
where
|
||||
H: FnMut(String, Arc<ServerFnTraitObj>) -> F,
|
||||
H: FnMut(String, ServerFunction) -> F,
|
||||
F: Filter<Extract = (R,), Error = warp::Rejection> + Send + Sync + 'static,
|
||||
F::Extract: Send,
|
||||
R: Reply + 'static,
|
||||
@@ -129,16 +125,48 @@ where
|
||||
/// ```
|
||||
pub fn register_server_fns(server_fn_route: &'static str) -> BoxedFilter<(impl Reply,)> {
|
||||
register_server_fns_with_handler(server_fn_route, |full_route, func| {
|
||||
path(full_route)
|
||||
.and(warp::post())
|
||||
let func2 = func.clone();
|
||||
let func3 = func.clone();
|
||||
path(full_route.clone())
|
||||
.and(warp::filters::method::get())
|
||||
.and(warp::header::headers_cloned())
|
||||
.and(warp::filters::query::raw())
|
||||
.and(warp::body::bytes())
|
||||
.and_then(move |headers: HeaderMap, body| {
|
||||
.and_then(move |headers, query, body| {
|
||||
let func = func.clone();
|
||||
async move {
|
||||
server_fn_handler(DioxusServerContext::default(), func, headers, body).await
|
||||
server_fn_handler(
|
||||
DioxusServerContext::default(),
|
||||
func,
|
||||
headers,
|
||||
Some(query),
|
||||
body,
|
||||
)
|
||||
.await
|
||||
}
|
||||
})
|
||||
.or(path(full_route.clone())
|
||||
.and(warp::filters::method::get())
|
||||
.and(warp::header::headers_cloned())
|
||||
.and(warp::body::bytes())
|
||||
.and_then(move |headers, body| {
|
||||
let func = func2.clone();
|
||||
async move {
|
||||
server_fn_handler(DioxusServerContext::default(), func, headers, None, body)
|
||||
.await
|
||||
}
|
||||
}))
|
||||
.or(path(full_route)
|
||||
.and(warp::filters::method::post())
|
||||
.and(warp::header::headers_cloned())
|
||||
.and(warp::body::bytes())
|
||||
.and_then(move |headers, body| {
|
||||
let func = func3.clone();
|
||||
async move {
|
||||
server_fn_handler(DioxusServerContext::default(), func, headers, None, body)
|
||||
.await
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -198,8 +226,9 @@ impl warp::reject::Reject for RecieveFailed {}
|
||||
/// A default handler for server functions. It will deserialize the request body, call the server function, and serialize the response.
|
||||
pub async fn server_fn_handler(
|
||||
server_context: impl Into<DioxusServerContext>,
|
||||
function: Arc<ServerFnTraitObj>,
|
||||
function: ServerFunction,
|
||||
headers: HeaderMap,
|
||||
query: Option<String>,
|
||||
body: Bytes,
|
||||
) -> Result<Box<dyn warp::Reply>, warp::Rejection> {
|
||||
let server_context = server_context.into();
|
||||
@@ -210,7 +239,12 @@ pub async fn server_fn_handler(
|
||||
tokio::runtime::Runtime::new()
|
||||
.expect("couldn't spawn runtime")
|
||||
.block_on(async {
|
||||
let resp = match function(server_context, &body).await {
|
||||
let query = &query.unwrap_or_default().into();
|
||||
let data = match &function.encoding {
|
||||
Encoding::Url | Encoding::Cbor => &body,
|
||||
Encoding::GetJSON | Encoding::GetCBOR => query,
|
||||
};
|
||||
let resp = match (function.trait_obj)(server_context, &data).await {
|
||||
Ok(serialized) => {
|
||||
// if this is Accept: application/json then send a serialized JSON response
|
||||
let accept_header =
|
||||
|
||||
Reference in new issue
Block a user