Closed kaylendog closed 1 year ago
Can't you just compile the Prisma Client into a dedicated crate which can be reused within your Cargo workspace for other crates? A build script shouldn't be required for that. If you were to use an include_proto
in each crate it would probs slow down your builds which wouldn't be optimal and using the macro in a single crate would be similar to the current setup with codegening the client into a single crate.
The microservices aren't contained within a workspace, they're all in separate repos. I can't commit the output of the generator since it is relative to the current workspace, and since it's generated I feel I shouldn't really be committing it anyway.
The first line of the generated script is always
pub static DATAMODEL_STR: &'static str =
include_str!("<absolute path to schema here>");
Which will fail if I try and bundle this up as a crate to another machine. I could edit this to be relative, but
If you were to use an include_proto in each crate it would probs slow down your builds which wouldn't be optimal and using the macro in a single crate would be similar to the current setup with codegening the client into a single crate.
It's more likely I'd stick the output of the macro in its own crate and specify that as a dependency elsewhere. Making another gross comparison to what tonic does, here's an example where I do this with tonic.
was typing out a response and then you said you're not using a workspace... that complicates things.
I don't think generating the client at build time or via a macro will ever be a good idea.
As for solutions to your problem - from what I understand of your situation I'm willing to meet you half way. DATAMODEL_STR
and MIGRATIONS_DIR
are resolved via absolute paths because MIGRATIONS_DIR
cannot be reliably resolved via relative paths (thanks include_dir!
and rustc
), but I could add a config option to the generator
part of the Prisma schema to specify a stable, relative path to the project that DATAMODEL_STR
and MIGRATIONS_DIR
can be resolved from.
This would allow the client to be put in a library and made portable, but it wouldn't fix your version mismatch problems - that's on your end, since each microservice would need to be updated when a new client is generated. I can't fathom not using a workspace for something like this, but if you really aren't able to then I think this part is out of my hands.
EDIT: I assume your project is Furink - While it's none of my business to dictate how you build your project, use a monorepo. It'll end up being less work for both of us haha.
That sounds helpful. Certainly seems better than my current build.rs
which replaces the absolute path with a relative one.
The version mismatch issues are much more manageable when it's just a dependency in Cargo.toml
I'm upgrading. I'm not using a workspace since the microservices are (slash will be, there's not a lot of them yet) written in various different languages - I could dump ones in the same languages into respective workspaces, but given each microservice might need different workflow pipelines in the future it made more sense to me to keep them separate.
I must ask about the conditional builds you mentionned - in reference to generating the client at build time, could you not just emit cargo:rerun-if-changed=prisma/schema.prisma
? This is what my current build script does and it works a charm.
EDIT: I assume your project is Furink - While it's none of my business to dictate how you build your project, use a monorepo. It'll end up being less work for both of us haha.
Heh, I don't deny it's a sensible idea. I just have some maintainability concerns (which I do admit may turn out to be of little concern anyway - still v early in development so I can't say for sure).
I could dump ones in the same languages into respective workspaces, but given each microservice might need different workflow pipelines in the future it made more sense to me to keep them separate.
As a maintainer of a large Rust + TS project, I don't think this should be a problem. Maybe Furink is different but how crazy could it be.
in reference to generating the client at build time, could you not just emit cargo:rerun-if-changed=prisma/schema.prisma?
yeah, you could. but i don't like it
Heh, I don't deny it's a sensible idea. I just have some maintainability concerns
IMO I think you should have more maintainability concerns around using microservices and separate repos. A monolith API powered by Prisma and rspc and a React frontend, all in a monorepo, will be way more maintainable. No gRPC, no microservices, just JSON kept in check by Rust and TypeScript.
Oh rspc looks quite nice - thank you for the recommendation. I'll have a play and see if my brain accepts the monolith idea!
Going to close this for now since I really don't want to allow and encourage the patterns that I've expressed disdain for in this thread, but if it's really necessary in future then feel free to create another issue outlining why using a workspace doesn't work.
There are a few cases in which
prisma-client-rust
having the ability to be used to generate a library is useful. In my particular case, I have a number of microservices, each of which deals with a separate part of the database, but all use the same schema. Having to include the prisma schema in every microservice repository is grounds for serious schema version mismatch problems.Using
prisma-client-rust
to generate a library crate for a given schema is currently pretty difficult. I have been messing about with build scripts to generate the client at compile time, but rust-analyser is very unhappy about this.It would be helpful to introduce a macro, akin to tonic's
include_proto
that expands to the prisma client generated byprisma generate
, along with a similarprisma_build::generate()
etc. that can be placed inbuild.rs
.