Best practices in temporal in handling evolving API contracts

We maintain long running workflows that interact with multiple services within the workflow based on a signal. We have an issue with evolving API contracts where it would introduce breaking changes or fields in the request or it could be bumping API versions. We have wrapped each API call in an activity method. What would be the best practice to handle such scenarios?

At the time the activity is making the API call, is there a way for it to tell which version of the API is now active? Is it possible, for example, for it to look at the activities arguments and see that it’s supposed to be making a call to the API version X, but now the API has a different version?

We have no mechanism on doing that right at the moment. Are we able to change the logic and input values of the activity method in such a case?

Oh, I had just been wondering if you might want to fail the activity if the current API turned out to be a later version…

Taking a step back, aside from Temporal, how do you find out that there’s a new version of the API? Do you know in advance that there’s going to be a change to the API? (Email: “Tomorrow at noon API version 8.3.6 will become active”) Do you run code and it breaks and you contact the team and they say “oh yeah we changed the API and didn’t tell anyone”? Do you have a way to check which version of the API is current?

I would say when it breaks that where we know as there are services that rapidly change and teams tend to forget to inform. Yeah checking the API version would be ideal and fail the activity but there is no way on doing it currently. I was thinking of a mechanism on handling rare cases of that sort as we dont want the client to resubmit it for us.

Well, if your activity throws an error, by default it’ll be retried. If you don’t want to retry the activity you have several options:

  • You can set a retry policy with the maximum number of attempts set to 1, and then it will never be retried. Note that this would also not retry other kinds of failures, such as temporary network problems.
  • If there’s a particular error that you know is associated with having a wrong API version, you can set “Non-Retryable Errors” in your retry policy, and then it won’t retry that particular error.
  • Or, if you know of some particular errors that you do want to retry, you could throw those from the activity but catch any others. If you catch an error you don’t want to retry, you can return normally from the activity (without throwing the exception) and return an object with a flag that says “failed”.