a seasoned dev like me should not be asking such a...
# random
s
a seasoned dev like me should not be asking such a newbie question, but.. 😅 when you deploy an update to two separate stacks/repos and the app will bomb if they’re not both live at the same time, how do you handle those scenarios? all I can think of putting some temporary conditions in place in one of the stacks that will handle either the old or new format. once everything is deployed, then remove those conditions & re-deploy that stack
c
well I may not answer your question but I got to say that’s one of the coolest things about working with CDK. on my company we only use Serverless framework (with the infrastructure generated by the
.yml
files), so we don’t have this option of like programming the infrastructure the way we want - for example in your case you can put an if condition and your stack will not be created. that’s super cool.
s
well, this isn’t really about resources in CloudFormation. I’m talking about just making a code change to the API, and a code change in a front-end stack that depends on the API
c
oh I see. well I’m kinda newbie here so don’t know how to do it too
s
no worries 🙂 it’s actually just a general question about conventions, not necessarily SST or CDK
d
Your last sentence is how I'd do it. When making breaking changes, we’ll always need an intermediate state that lets the dependencies switch over.
Support both designs and aggressively migrate otherwise you now have two systems 😂
d
I think as well as more to do with change management in general than serverless specifically. In my experience the best practice is to actually never do breaking changes all in once. 1. You first introduce the new API as a new version or endpoint this also helps to adopt Tracer bullet programming 2. after being deployed for long enough to test it and be confident about it you should deploy what is consuming it. At this point you are still able to rollback if needed. 3. The last deployment should remove the deprecated API
s
I would try and do as @Davide Ungari suggests, bonus points if you add metrics to track usage of the old/new formats so you know when someone stops using your old version, and can them remove it
s
@Davide Ungari sorry, I probably wasn’t clear in stating my problem it’s not about releasing new features. we can do feature flags for those, and roll out new stuff to increasingly larger %’s of our customer base. my problem is, if I have to update an existing feature, and changes were made to both the back end and the front end, but the back end takes longer to go through CI/CD than the front end.
d
My fault I'm not precise enough in the terminology. When in point 1 I wrote:
You first introduce the new API as a new version or endpoint this also helps to adopt...
I meant a change to an existing endpoint ( new was a misleading word ), anyway let's do an example. You have your API endpoint
/rest/users/me
that returns details of the current user. You want to change it but the change is not retro-compatible, is not just adding a new field is something more complex maybe even changing the data model behind... What I'm suggesting is to do some sort of versioning
/rest/v2/users/me
so you can easily deploy the new endpoint even before is actually used.
When I say test it... I mean an holistic way, the fact that you are able to deploy it is already a test, maybe some performance tests also in production and obviously functional tests ...
I give you a more general angle, one lean development best practice is to work in small batches to keep risk under control. Even if it seems more work actually on the long run is faster and safer approach: https://cloud.google.com/architecture/devops/devops-process-working-in-small-batches
s
@Davide Ungari thanks for clarifying! so you’re saying if the front end & back end are both changing to accommodate some change in the architecture, to create a new API route, deploy that, and then update the front end to use that new route, then deploy? it seems excessive to bump the version just for what could be a minor change. and then the rest of the routes are a different version which could be confusing I can’t help but wonder if there’s a cleaner way
o
It depends whether you want to UI to keep working or just show a message and wait around for the API It needs to come up. If it needs to work throughout then either one backend needs to support multiple versions of the API, or you have multiple versions of the API running (which means your data model needs to support multiple models). I don’t there’s a way around that complexity. Otherwise the API can publish a version, and clients know what version of the API they need (and it can use semantic versioning rules!) With UI there’s always a chance that some old cached version makes a request