Recommended way to build up file structure?
one approach I've been taking is to group my convex directory into related data models, and create a queries.ts, mutations.ts, and actions.ts. Is there any recommended approach that others like doing for larger convex projects?

17 Replies
@Web Dev Cody this is pretty common. some folks also put the model in a
model.ts
file with the queries/mutations together
meaning, plans would just be plans.ts
but as a codebase grows, some models get broken up further into directories, and sometimes queries and mutations are separated like thisMy ideal would be a semantic tree, and I wouldn't worry about splitting read/write/action. So
plans > sections.ts
, and when I want to break up sections I would turn it into a directory.
This only really works before going public, afterwards you'd want to maintain backwards compatibility. So another angle is to think of a fairly future proof name for a function (perhaps building out the directory structure even before the complexity warrants it).On the backwards compatibility front, for API breaking changes it's sometimes easier to change the function to a new one (and keep the old deprecated one with the old API until clients drop off), since you'll only get new clients to the new endpoint. an extreme example of this is to make a
v2
directory for a new API, and pass around a reference to api.v2
to all functions, leaving the original functions there until you can sunset them.
Then when you change latest
to a new version, you will get type errors everywhere that your new API breaks the old types.
This is a concept only right now - haven't actually done it. It's nice that you avoid breaking old clients b/c typescript forces you to fix older code when the data model changes, so long as you're careful not to change the arguments / return types while you're refactoring.@ian @Michal Srb so, you mention that you'd use a semantic tree, but my main complaint is the moment I need 'use node', I can no longer follow a semantic tree
so I'm basically forced to split by technology
I guess I still just need to find what works best for my thought process, because 'use node' forces my hand to pull out mutation the moment a single action needs node functionality
yep, right now this part is admittedly awkward
in a perfect world we'd be able to annotate individual functions or whatever as use node
but we're relying on existing toolchains/bundlers etc and this is hard to achieve so far.
the hope is over time more and more stuff doens't require 'use node' b/c it has a lot of other tradeoffs
but some things will always need it, and we don't love right now that you need a separate module just for that
one example, maybe you have a better solution, I just wanted to generate a randomUUID using the node's crypto library
is there a way to do that inside a mutation?
without needing the node library?
like to generate an random API key
or
crypto.randomBytes(16).toString('hex')
we do support the web crypto api in our runtime
I'm guessing using crypto is much more secure than Math.random()
oh
I think @sshader had a pretty nice list of what's supported / unsupported right now, but I can't find it in the docs currently 😕
I guess I should read this a bit
Runtimes | Convex Developer Hub
Convex functions can run in two runtimes:
ah yeah, I should have expanded
Yeah @Web Dev Cody, I pretty much never have to use Node these days. Any time you're forced to use Node, let us know.
so is crypto just a global thing we have access to?
let me just test real quick, not sure why I'm asking
looks like the
randomUUID
method might be the thingyeah this works fine
I guess I wasn't aware it's just a global 😆
cool! yeah, our runtime is more like the browser runtime than node.js
(or a big cloud's "edge" runtime, but same idea)
so often the API you're looking for is more in that documentation culture than node's