Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add more options for generating server fn routes #3438

Merged
merged 6 commits into from
Jan 25, 2025

Conversation

spencewenski
Copy link
Contributor

@spencewenski spencewenski commented Jan 3, 2025

Summary

This PR adds a few different options to customize the generated server fn API routes.

Configure the default prefix

Allow configuring the default prefix for server function API routes. This is useful to override the default prefix (/api) for all server functions without needing to manually specify via #[server(prefix = "...")] on every server function.

Allow disabling the server fn hash

Also, allow disabling appending the server functions' hashes to the end of their API names. This is useful when an app's client side needs a stable server API. For example, shipping the CSR WASM binary in a Tauri app. Tauri app releases are dependent on each platform's distribution method (e.g., the Apple App Store or the Google Play Store), which typically are much slower than the frequency at which a website can be updated. In addition, it's common for users to not have the latest app version installed. In these cases, the CSR WASM app would need to be able to continue calling the backend server function API, so the API path needs to be consistent and not have a hash appended.

Module path in server fn API route

Allow including the module path of the server function in the API route. This is an alternative strategy to prevent duplicate server function API routes (the default strategy is to add a hash to the end of the route). Each element of the module path will be separated by a /. For example, a server function with a fully qualified name of parent::child::server_fn would have an API route of /api/parent/child/server_fn (possibly with a different prefix and a hash suffix depending on the values of the other server fn configs).

Example

As an example, I have a server function called current_user in a sub-crate called web with module path app::account::context::current_user, I have /api/fn set as the default prefix, and I have the hash suffix disabled. This results in the following API route: /api/fn/web/app/account/context/current_user/current_user.

Related PRs

I also opened a cargo-leptos PR to add support for setting the env vars based on values in the leptos config: leptos-rs/cargo-leptos#412

spencewenski added a commit to spencewenski/cargo-leptos that referenced this pull request Jan 3, 2025
Add support to configure and set the `SERVER_FN_PREFIX` and
`DISABLE_SERVER_FN_HASH` env vars using the leptos project config.

See the following PR for more info: leptos-rs/leptos#3438
spencewenski added a commit to spencewenski/cargo-leptos that referenced this pull request Jan 3, 2025
Add support to configure and set the `SERVER_FN_PREFIX` and
`DISABLE_SERVER_FN_HASH` env vars using the leptos project config.

See the following PR for more info: leptos-rs/leptos#3438
@benwis
Copy link
Contributor

benwis commented Jan 6, 2025

Overall I think this looks good and would be a useful change. The hashes were added by default primarily to prevent collisions between server fn paths. Have you experimented to see what happens in that case? If I recall correctly it should throw an error.

Otherwise I think this is good to go

@spencewenski
Copy link
Contributor Author

The hashes were added by default primarily to prevent collisions between server fn paths. Have you experimented to see what happens in that case?

Yeah, Axum throws an error when you try to add a duplicate route. I can add a comment calling this out. I think it’s okay though since removing the hashes is an opt-in behavior.

I was thinking another option to prevent conflicts could be to use the module path as the prefix for the api route. From what I was seeing though that’s not possible in macros, but I’m not super familiar with macros so I could be wrong.

@benwis
Copy link
Contributor

benwis commented Jan 7, 2025

The hashes were added by default primarily to prevent collisions between server fn paths. Have you experimented to see what happens in that case?

Yeah, Axum throws an error when you try to add a duplicate route. I can add a comment calling this out. I think it’s okay though since removing the hashes is an opt-in behavior.

I was thinking another option to prevent conflicts could be to use the module path as the prefix for the api route. From what I was seeing though that’s not possible in macros, but I’m not super familiar with macros so I could be wrong.

A comment's good, overall I don't think we have to worry about additional conflict detection as long as it throws a proper error

@spencewenski
Copy link
Contributor Author

Yeah, Axum throws an error when you try to add a duplicate route.

I was double checking this, and I was correct that Axum throws an error. However, it appears that Actix doesn't. In that case, do we want to add a check somewhere in Leptos?

@spencewenski
Copy link
Contributor Author

spencewenski commented Jan 7, 2025

I was thinking another option to prevent conflicts could be to use the module path as the prefix for the api route. From what I was seeing though that’s not possible in macros, but I’m not super familiar with macros so I could be wrong.

I actually figured out how to do this. It would require adding const-str as a dependency in server_fn, similar to how const_format is added as a dependency. I think I would be interested in this for my project, so I'll open this as a separate PR.

Here's the code: spencewenski#1. I'll move the PR to the main leptos repo once this PR is merged. I added this to this PR.

@spencewenski spencewenski requested a review from benwis January 12, 2025 22:26
@spencewenski
Copy link
Contributor Author

Hey @benwis , are you able to review/approve this?

Allow configuring the default prefix for server function API routes. This is useful to
override the default prefix (`/api`) for all server functions without needing to manually
specify via `#[server(prefix = "...")]` on every server function.

Also, allow disabling appending the server functions' hashes to the end of their API names.
This is useful when an app's client side needs a stable server API. For example, shipping
the CSR WASM binary in a Tauri app. Tauri app releases are dependent on each platform's
distribution method (e.g., the Apple App Store or the Google Play Store), which typically
are much slower than the frequency at which a website can be updated. In addition, it's
common for users to not have the latest app version installed. In these cases, the CSR WASM
app would need to be able to continue calling the backend server function API, so the API
path needs to be consistent and not have a hash appended.
Allow including the module path of the server function in the API route. This
is an alternative strategy to prevent duplicate server function API routes
(the default strategy is to add a hash to the end of the route). Each element
of the module path will be separated by a `/`. For example, a server function
with a fully qualified name of `parent::child::server_fn` would have an API
route of `/api/parent/child/server_fn` (possibly with a different prefix and
a hash suffix depending on the values of the other server fn configs).
@spencewenski spencewenski force-pushed the server-fn-default-config branch from 4418393 to f246c5b Compare January 25, 2025 02:56
@spencewenski spencewenski changed the title feat: Allow disabling server fn hash and customizing the default prefix feat: Add more options for generating server fn paths Jan 25, 2025
@spencewenski spencewenski changed the title feat: Add more options for generating server fn paths feat: Add more options for generating server fn routes Jan 25, 2025
@spencewenski spencewenski changed the base branch from main to leptos_0.8 January 25, 2025 03:03
spencewenski added a commit to spencewenski/cargo-leptos that referenced this pull request Jan 25, 2025
Add support to configure and set the `SERVER_FN_PREFIX` and
`DISABLE_SERVER_FN_HASH` env vars using the leptos project config.

See the following PR for more info: leptos-rs/leptos#3438
@spencewenski
Copy link
Contributor Author

Hey @gbj, no rush, but can you take a look at this when you get a chance? I'm hoping to get this into 0.8 because it requires a semver breaking change to the LeptosOptions struct.

@benwis
Copy link
Contributor

benwis commented Jan 25, 2025

As is I think this makes sense and works pretty well. I do feel like you might want to version the server fn api for your use case of different versions

@benwis
Copy link
Contributor

benwis commented Jan 25, 2025

@spencewenski the checks here say you're missing a ServerFnError import in the actix file. If you can make those pass I'm happy to merge

@spencewenski
Copy link
Contributor Author

spencewenski commented Jan 25, 2025

As is I think this makes sense and works pretty well. I do feel like you might want to version the server fn api for your use case of different versions

@benwis Can you elaborate on this? Do you mean bump the server_fn and server_fn_macro crates? Or do you mean I would want to version my APIs in my application?

@spencewenski the checks here say you're missing a ServerFnError import in the actix file. If you can make those pass I'm happy to merge

This appears to be broken in the leptos_0.8 branch -- it was broken in a previous PR too. I can fix try to fix it though if you want.

@benwis
Copy link
Contributor

benwis commented Jan 25, 2025

As is I think this makes sense and works pretty well. I do feel like you might want to version the server fn api for your use case of different versions

Can you elaborate on this? Do you mean bump the server_fn and server_fn_macro crates? Or do you mean I would want to version my APIs in my application?

@spencewenski the checks here say you're missing a ServerFnError import in the actix file. If you can make those pass I'm happy to merge

This appears to be broken in the leptos_0.8 branch -- it was broken in a previous PR too. I can fix try to fix it though if you want.

* PR: [chore: upgrade `axum` to `v0.8` #3439](https://github.com/leptos-rs/leptos/pull/3439)

* Workflow run: https://github.com/leptos-rs/leptos/actions/runs/12834906687/job/35793186558

Oh yeah, for versioning this isn't a PR change, but for example you might have a version endpoint or you might have your server fn URL include the api version.

I see that it's broken elsewhere, if you'd like to fix it it looks easy, otherwise I'll just merge this and then try to fix it.

EDIT: I see you beat me to it

@benwis
Copy link
Contributor

benwis commented Jan 25, 2025

Well that's fun and unlikely to be related to this PR. So I'll merge this and figure the rest out later

@benwis benwis merged commit 2b589fa into leptos-rs:leptos_0.8 Jan 25, 2025
1 check failed
@spencewenski
Copy link
Contributor Author

Thanks for your help, @benwis! 🎉

@spencewenski spencewenski deleted the server-fn-default-config branch January 25, 2025 04:15
@benwis
Copy link
Contributor

benwis commented Jan 25, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants