Hey again, we're implementing bi direcitional cont...
# general
p
Hey again, we're implementing bi direcitional contract testing in order to ensure backwards compatible releases, but struggling with how to enforce backwards compadibility. We have a FE and BE We could enforce that any merge to main is compatible with the opposite service main branch contract AND deployed to prod contract. But this means if we want to do a breaking BE change (removing an endpoint), we have to wait until the new FE (without the endpoint call) is deployed to prod until we can merge that PR. This would ensure that if that FE does not deploy until BE is ready for it, and it can safely rollback But this really slows down devs, they can't merge their pr until BE is in prod. We could have seperate can i merge and can i deploy checks, Prs do can-i-merge with the opposite main contract, and Deployments check if the contract is compatible with the opposite prod contract, but this means that we could have a issue only when we start the release process, when we notice that new version of BE is not compatible with old version of FE. Is this just generally expected, as in devs should always code backwards compatible, and if they don't its going to show up at deploy time. Or should we just block at merge, devs need to make sure everything into main could be deployed instantly, so it's on them to make it backwards compatible or wait until the new version of the BE is out. thanks For context we usually deploy FE and BE at same time, but want to be able to deploy independently, so we need to check new FE works with old BE and vice versa
j
The traditional approach when replacing something (be it a field in a schema, an endpoint, etc.) is "expand then contract", which is inherently multi-step: 1. Add the new endpoint on the BE. It now serves both, which is a (hopefully temporary) increased maintenance burden. Depending on the team, you might raise a draft PR to remove the old endpoint, or create a ticket scheduled for some weeks' time. 2. All consumers switch to the new endpoint. There's no need to maintain compatibility with both from the consumer's perspective, just a wholesale switch. 3. Once all consumers have migrated, Pact will be happy with the removal of the old endpoint, and that cleanup branch can be merged and deployed. On your can-i-merge vs can-i-deploy question: blocking at merge is the stricter approach and generally the right one as it ensures
main
is always deployable and puts the responsibility on the developer to either make their change backwards compatible or coordinate the steps above. The alternative (only checking at deploy time) lets problems slip through to the release process, which tends to be a worse time to discover them. You mention FE and BE are currently always deployed in sync, so this might feel like overkill right now, but since you're moving toward independent deployment, adopting the multi-step process will make that sustainable without the "wait for prod" problem you described.
p
Thankyou!
❤️ 1
m
Ah, thank for you beating me to it Josh and also explaining it so well. Ultimately, we aim to provide the tools so you can always change and adapt them to your workflow as things change. You have shown a decent understanding of the decision points in your current setup, and hopefully this helps. Best of luck!