Feature Request
Motivation
I often write web+desktop portable applications split into three crates: a frontend, a backend, and an api crate.
The backend crate uses axum, and the frontend crate some form of cross-platform UI framework, something that both compiles to WASM and native platforms.
Both frontend and backend crates depend on the api crate, which is mostly a bunch of types with derive(Serialize, Deserialize).
I try to keep as much of the type safety of requests and responses in the shared api crate, and this pattern works great for extractors like Json.
I'd love to put types that derive TypedPath into the shared api crate, so that the frontend can use the to_uri and with_query_params convenience methods to keep the paths in sync with the Router on the backend. In theory, I can do that, but doing so also pulls a lot of dependencies into the frontend crate, including axum, which is something I would like to avoid, especially if I'm compiling for WASM.
Proposal
Could the TypedPath trait and derive be split into a separate crate and re-exported, to avoid having to pull in all of the axum_extra dependencies if all that's needed is a consistent representation of request URLs? The headers crate is currently re-exported in a similar way by the typed-header feature. The axum-specific parts, like RouterExt, would remain in axum_extra.
The Resource helper would also make sense to expose outside of axum, but that one is tougher due to how coupled it is to Router (which is also what makes it ergonomic).
Alternatives
Currently, my workaround is to duplicate the work in the api crate with both a backend-centric and a frontend-centric implementation. The former uses TypedPath and is feature-gated, and the latter uses manually written format!s. The two are kept in sync by unit tests. It is not very ergonomic, and it's easy to forget to add unit tests for new paths.
I have not yet found a better alternative, but suggestions would be welcome! 😄
Feature Request
Motivation
I often write web+desktop portable applications split into three crates: a
frontend, abackend, and anapicrate.The
backendcrate usesaxum, and the frontend crate some form of cross-platform UI framework, something that both compiles to WASM and native platforms.Both
frontendandbackendcrates depend on theapicrate, which is mostly a bunch of types withderive(Serialize, Deserialize).I try to keep as much of the type safety of requests and responses in the shared
apicrate, and this pattern works great for extractors likeJson.I'd love to put types that derive
TypedPathinto the sharedapicrate, so that thefrontendcan use theto_uriandwith_query_paramsconvenience methods to keep the paths in sync with theRouteron thebackend. In theory, I can do that, but doing so also pulls a lot of dependencies into thefrontendcrate, includingaxum, which is something I would like to avoid, especially if I'm compiling for WASM.Proposal
Could the
TypedPathtrait and derive be split into a separate crate and re-exported, to avoid having to pull in all of theaxum_extradependencies if all that's needed is a consistent representation of request URLs? Theheaderscrate is currently re-exported in a similar way by thetyped-headerfeature. Theaxum-specific parts, likeRouterExt, would remain inaxum_extra.The
Resourcehelper would also make sense to expose outside ofaxum, but that one is tougher due to how coupled it is toRouter(which is also what makes it ergonomic).Alternatives
Currently, my workaround is to duplicate the work in the
apicrate with both abackend-centric and afrontend-centric implementation. The former usesTypedPathand is feature-gated, and the latter uses manually writtenformat!s. The two are kept in sync by unit tests. It is not very ergonomic, and it's easy to forget to add unit tests for new paths.I have not yet found a better alternative, but suggestions would be welcome! 😄