kabb8048
kabb804812mo ago

Function "versions" / Behavior across deployments

First off - really loving Convex! The DX is astounding, and I love that it allows me to "not think about" things, however to trust Convex really handles those things well, I need to have a high-level understanding of how it all works. The docs surrounding caching, consistency, idempotent mutations, deterministic queries all give me comfort that I can just ignore transactions essentially, and "trust the reactor" - thank you for the wonderful docs there and also James's talk on Software Engineering Daily really helped. One thing that wasn't clear to me from the docs, was how functions work across deploys. For example, if I have deploy a version of my software with a query Q1, and then deploy another version where Q1 is either renamed, removed, or edited. What happens when frontend clients (with a cached version of the page for example) call Q1? Does convex do anything special here? Or do I just need to treat the filepath + exported function name as the "stable identifier" of a function - and treat it with the same respect and backwards compatibility requirements that I would a normal API endpoint?
8 Replies
jamwt
jamwt12mo ago
@kabb8048 thanks for the kind words! you've identified a current gap. we're not doing very much right now to help you with API versioning, so there's no magic here. if you want a seamless upgrade process, it's on you a bit to have some sort of gradual rollout plan with an ability to force reload or whatever on long-running old versions in browsers. we have some ideas to help more with this, but they're not built yet
kabb8048
kabb8048OP12mo ago
OK, makes sense - so if I deploy an updated function named "api.module:functionName", all old clients will automatically start to query the recently deployed function. And if I rename a function from "api.module:functionName" to "api.module:functionName2" then I have essentially broken all clients until they get the updated frontend code. This could obviously break the "end-to-end typesafety" promise of Convex, but as long as we know the constraints we are operating under we (the developers) can build something robust. Thanks a ton!
jamwt
jamwt12mo ago
no problem. and to be clear, your backend code is deployed atomically. but the application code, yeah. it's on you
kabb8048
kabb8048OP12mo ago
Ya, makes sense - though even that I feel like could use a bit of a deeper explanation on the site. Like what happens if I schedule a function to run in 15 minutes, but then convex deploy removing that function? In other words, am I queuing the function or queueing the function reference? (give your explanation, it certainly feels like they're just the function names, so this isnt'n really something I'm confused at anymore - but just stating that even outside of any application code, this problem exists). I think the root of my confusion is that convex handles the stable identifiers for my functions, and in traditional web development I am used to being able to change the code name of my API functions (and choose to change or keep the API endpoint). Renaming a function is usually not something that constitutes a breaking API Change, but in Convex it is.
ballingt
ballingt12mo ago
You are queuing the function reference, which is generally what you want; this way you can update the code if you want to. This way you don't get stuck with a function scheduled to run in a month that you can't update the code for. I see where you're coming from re "renaming a function;" Convex uses file-based routing similar to Next.js and several other web frameworks where the module a function is defined in and the export symbol it is bound to determine the API path. There could be an explicit routing system in Convex, this isn't fundamental to the Convex model. It's just a preference that most developers we talked to had when designing the layout of the convex/ directory. What's the backend framework that you're using to think about traditional web development you're used to? e.g. Express, Django, Rails?
kabb8048
kabb8048OP12mo ago
Ya, all makes sense to me, and I agree that function reference is what is wanted. I'm not arguing for a change at all, its just that it wasn't quite clear to me at first. Perhaps there is a line in the docs that says "Convex uses file-based routing similar to Next.js and several other web frameworks where the module a function is defined in and the export symbol it is bound to determine the API path", but I missed it. Just that sentence alone would have cleared it all up for me. And honestly that's what I would have assumed as well for Convex if it weren't for the list of mind-blowing features that it has ready out of the box. Basically y'all convinced me Convex was magic, so I was looking for more magic. Anyway, its all clear to me now!
ballingt
ballingt12mo ago
Thanks for this feedback, really helpful to hear how this lands! Hearing your initial impressions helps these concepts fight for space in the docs :)
ian
ian12mo ago
yeah, if you're changing your API you'll have to think about it. Some options: - You can add a new named argument as optional - You can make a new function and leave the old one until old clients go away - You can have your client query what the version of the server is, and prompt the user to refresh when it's out of date

Did you find this page helpful?