Skip to content

Commit b2136f1

Browse files
authored
feat: Add server function configs (#412)
1 parent f40367c commit b2136f1

10 files changed

+113
-21
lines changed

examples/project/Cargo.toml

+21-17
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,25 @@ opt-level = 'z'
4646
[features]
4747
default = ["ssr"]
4848
hydrate = [
49-
"leptos/hydrate",
50-
"leptos_meta/hydrate",
51-
"leptos_router/hydrate",
52-
"dep:wasm-bindgen",
53-
"dep:console_log",
54-
"dep:console_error_panic_hook",
49+
"leptos/hydrate",
50+
"leptos_meta/hydrate",
51+
"leptos_router/hydrate",
52+
"dep:wasm-bindgen",
53+
"dep:console_log",
54+
"dep:console_error_panic_hook",
5555
]
5656
ssr = [
57-
"leptos/ssr",
58-
"leptos_meta/ssr",
59-
"leptos_router/ssr",
60-
"dep:leptos_actix",
61-
"dep:reqwest",
62-
"dep:actix-web",
63-
"dep:actix-files",
64-
"dep:futures",
65-
"dep:simple_logger",
66-
"dep:serde_json",
67-
"dep:dotenvy",
57+
"leptos/ssr",
58+
"leptos_meta/ssr",
59+
"leptos_router/ssr",
60+
"dep:leptos_actix",
61+
"dep:reqwest",
62+
"dep:actix-web",
63+
"dep:actix-files",
64+
"dep:futures",
65+
"dep:simple_logger",
66+
"dep:serde_json",
67+
"dep:dotenvy",
6868
]
6969

7070

@@ -122,3 +122,7 @@ env = "dev"
122122
#
123123
# Optional: Defaults to false. Can also be set with the LEPTOS_HASH_FILES=false env var
124124
hash-files = true
125+
126+
server-fn-prefix = "/custom/prefix"
127+
disable-server-fn-hash = true
128+
server-fn-mod-path = true

examples/workspace/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ lib-package = "front-package"
2828
assets-dir = "project1/assets"
2929
style-file = "project1/css/main.scss"
3030
site-root = "target/site/project1"
31+
server-fn-prefix = "/custom/prefix"
32+
disable-server-fn-hash = true
33+
server-fn-mod-path = true

src/compile/tests.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ fn test_project_dev() {
5959
LEPTOS_JS_MINIFY=false \
6060
LEPTOS_HASH_FILES=true \
6161
LEPTOS_HASH_FILE_NAME=hash.txt \
62-
LEPTOS_WATCH=true";
62+
LEPTOS_WATCH=true \
63+
SERVER_FN_PREFIX=/custom/prefix \
64+
DISABLE_SERVER_FN_HASH=true \
65+
SERVER_FN_MOD_PATH=true";
6366
assert_eq!(ENV_REF, envs);
6467

6568
assert_snapshot!(cargo, @"cargo build --package=example --bin=example --no-default-features --features=ssr");
@@ -107,7 +110,10 @@ fn test_workspace_project1() {
107110
LEPTOS_BIN_DIR=project1\\server \
108111
LEPTOS_JS_MINIFY=false \
109112
LEPTOS_HASH_FILES=false \
110-
LEPTOS_WATCH=true"
113+
LEPTOS_WATCH=true \
114+
SERVER_FN_PREFIX=/custom/prefix \
115+
DISABLE_SERVER_FN_HASH=true \
116+
SERVER_FN_MOD_PATH=true"
111117
} else {
112118
"\
113119
LEPTOS_OUTPUT_NAME=project1 \
@@ -119,7 +125,10 @@ fn test_workspace_project1() {
119125
LEPTOS_BIN_DIR=project1/server \
120126
LEPTOS_JS_MINIFY=false \
121127
LEPTOS_HASH_FILES=false \
122-
LEPTOS_WATCH=true"
128+
LEPTOS_WATCH=true \
129+
SERVER_FN_PREFIX=/custom/prefix \
130+
DISABLE_SERVER_FN_HASH=true \
131+
SERVER_FN_MOD_PATH=true"
123132
};
124133

125134
let cli = dev_opts();

src/config/dotenvs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ fn overlay(conf: &mut ProjectConfig, envs: impl Iterator<Item = (String, String)
5555
"LEPTOS_BIN_TARGET_DIR" => conf.bin_target_dir = Some(val),
5656
"LEPTOS_BIN_CARGO_COMMAND" => conf.bin_cargo_command = Some(val),
5757
"LEPTOS_JS_MINIFY" => conf.js_minify = val.parse()?,
58+
"SERVER_FN_PREFIX" => conf.server_fn_prefix = Some(val),
59+
"DISABLE_SERVER_FN_HASH" => conf.disable_server_fn_hash = true,
5860
// put these here to suppress the warning, but there's no
5961
// good way at the moment to pull the ProjectConfig all the way to Exe
6062
exe::ENV_VAR_LEPTOS_TAILWIND_VERSION => {}

src/config/project.rs

+48-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pub struct Project {
4747
pub hash_file: HashFile,
4848
pub hash_files: bool,
4949
pub js_minify: bool,
50+
pub server_fn_prefix: Option<String>,
51+
pub disable_server_fn_hash: bool,
52+
pub server_fn_mod_path: bool,
5053
}
5154

5255
impl Debug for Project {
@@ -64,6 +67,9 @@ impl Debug for Project {
6467
.field("site", &self.site)
6568
.field("end2end", &self.end2end)
6669
.field("assets", &self.assets)
70+
.field("server_fn_prefix", &self.server_fn_prefix)
71+
.field("disable_server_fn_hash", &self.disable_server_fn_hash)
72+
.field("server_fn_mod_path", &self.server_fn_mod_path)
6773
.finish_non_exhaustive()
6874
}
6975
}
@@ -126,6 +132,9 @@ impl Project {
126132
hash_file,
127133
hash_files: config.hash_files,
128134
js_minify: cli.release && cli.js_minify && config.js_minify,
135+
server_fn_prefix: config.server_fn_prefix,
136+
disable_server_fn_hash: config.disable_server_fn_hash,
137+
server_fn_mod_path: config.server_fn_mod_path,
129138
};
130139
resolved.push(Arc::new(proj));
131140
}
@@ -159,7 +168,16 @@ impl Project {
159168
vec.push(("LEPTOS_HASH_FILE_NAME", self.hash_file.rel.to_string()));
160169
}
161170
if self.watch {
162-
vec.push(("LEPTOS_WATCH", "true".to_string()))
171+
vec.push(("LEPTOS_WATCH", true.to_string()))
172+
}
173+
if let Some(prefix) = self.server_fn_prefix.as_ref() {
174+
vec.push(("SERVER_FN_PREFIX", prefix.clone()));
175+
}
176+
if self.disable_server_fn_hash {
177+
vec.push(("DISABLE_SERVER_FN_HASH", true.to_string()));
178+
}
179+
if self.server_fn_mod_path {
180+
vec.push(("SERVER_FN_MOD_PATH", true.to_string()));
163181
}
164182
vec
165183
}
@@ -226,6 +244,35 @@ pub struct ProjectConfig {
226244
#[serde(default)]
227245
pub bin_default_features: bool,
228246

247+
/// The default prefix to use for server functions when generating API routes. Can be
248+
/// overridden for individual functions using `#[server(prefix = "...")]` as usual.
249+
///
250+
/// This is useful to override the default prefix (`/api`) for all server functions without
251+
/// needing to manually specify via `#[server(prefix = "...")]` on every server function.
252+
#[serde(default)]
253+
pub server_fn_prefix: Option<String>,
254+
255+
/// Whether to disable appending the server functions' hashes to the end of their API names.
256+
///
257+
/// This is useful when an app's client side needs a stable server API. For example, shipping
258+
/// the CSR WASM binary in a Tauri app. Tauri app releases are dependent on each platform's
259+
/// distribution method (e.g., the Apple App Store or the Google Play Store), which typically
260+
/// are much slower than the frequency at which a website can be updated. In addition, it's
261+
/// common for users to not have the latest app version installed. In these cases, the CSR WASM
262+
/// app would need to be able to continue calling the backend server function API, so the API
263+
/// path needs to be consistent and not have a hash appended.
264+
#[serde(default)]
265+
pub disable_server_fn_hash: bool,
266+
267+
/// Include the module path of the server function in the API route. This is an alternative
268+
/// strategy to prevent duplicate server function API routes (the default strategy is to add
269+
/// a hash to the end of the route). Each element of the module path will be separated by a `/`.
270+
/// For example, a server function with a fully qualified name of `parent::child::server_fn`
271+
/// would have an API route of `/api/parent/child/server_fn` (possibly with a
272+
/// different prefix and a hash suffix depending on the values of the other server fn configs).
273+
#[serde(default)]
274+
server_fn_mod_path: bool,
275+
229276
#[serde(skip)]
230277
pub config_dir: Utf8PathBuf,
231278
#[serde(skip)]

src/config/snapshots/cargo_leptos__config__tests__workspace.snap

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
source: src/config/tests.rs
33
expression: conf
4+
snapshot_kind: text
45
---
56
Config {
67
projects: [
@@ -71,6 +72,11 @@ Config {
7172
dir: "project1/assets",
7273
},
7374
),
75+
server_fn_prefix: Some(
76+
"/custom/prefix",
77+
),
78+
disable_server_fn_hash: true,
79+
server_fn_mod_path: true,
7480
..
7581
},
7682
Project {
@@ -144,6 +150,9 @@ Config {
144150
dir: "project2/src/assets",
145151
},
146152
),
153+
server_fn_prefix: None,
154+
disable_server_fn_hash: false,
155+
server_fn_mod_path: false,
147156
..
148157
},
149158
],

src/config/snapshots/cargo_leptos__config__tests__workspace_bin_args_project2.snap

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
source: src/config/tests.rs
33
expression: conf
4+
snapshot_kind: text
45
---
56
Config {
67
projects: [
@@ -80,6 +81,9 @@ Config {
8081
dir: "project2/src/assets",
8182
},
8283
),
84+
server_fn_prefix: None,
85+
disable_server_fn_hash: false,
86+
server_fn_mod_path: false,
8387
..
8488
},
8589
],

src/config/snapshots/cargo_leptos__config__tests__workspace_in_subdir_project2.snap

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
source: src/config/tests.rs
33
expression: conf
4+
snapshot_kind: text
45
---
56
Config {
67
projects: [
@@ -75,6 +76,9 @@ Config {
7576
dir: "project2/src/assets",
7677
},
7778
),
79+
server_fn_prefix: None,
80+
disable_server_fn_hash: false,
81+
server_fn_mod_path: false,
7882
..
7983
},
8084
],

src/config/snapshots/cargo_leptos__config__tests__workspace_project1.snap

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
source: src/config/tests.rs
33
expression: conf
4+
snapshot_kind: text
45
---
56
Config {
67
projects: [
@@ -71,6 +72,11 @@ Config {
7172
dir: "project1/assets",
7273
},
7374
),
75+
server_fn_prefix: Some(
76+
"/custom/prefix",
77+
),
78+
disable_server_fn_hash: true,
79+
server_fn_mod_path: true,
7480
..
7581
},
7682
],

src/config/snapshots/cargo_leptos__config__tests__workspace_project2.snap

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
source: src/config/tests.rs
33
expression: conf
4+
snapshot_kind: text
45
---
56
Config {
67
projects: [
@@ -75,6 +76,9 @@ Config {
7576
dir: "project2/src/assets",
7677
},
7778
),
79+
server_fn_prefix: None,
80+
disable_server_fn_hash: false,
81+
server_fn_mod_path: false,
7882
..
7983
},
8084
],

0 commit comments

Comments
 (0)