I was wondering if anyone had an effective pattern they had found for versioning of their REST API. The mobile client developers would like some concurrent API support for breaking changes to the API, so that they don’t have to force people to upgrade immediately upon new app release. It’s causing me some difficulty, because the two patterns that naturally come up for me both have their difficulties:
- I create a large serverless deployment, and within it I copy and paste both the configuration for the interface from “v1” to “v2”, etc. in the serverless.yml file, and I also make copies of code in subdirectories that match the interface versions.
- I create smaller serverless deployments called “v1” and “v2”, and then either convert them to reference data structures contained in a third serverless “resources” deployment, or somehow implement consistency across the data structures contained in each stage for the duration of the overlap between them.
The first feels more like going against the functionality of git, and the latter feels more like going against the functionality of serverless. I have strong reservations around the sharing of data structures, for at least the issue that if a versioning changes the way that data is stored in the data structures, it could be very hard or impossible to maintain an old interface’s access to the same data. But, without another, better option, I’m feeling the pull towards #2.
Has anyone designed something more effective than this?
Thanks in advance.
I think you’re right to want to keep a single code base and data set. Two other options that come to mind are:
- Configure Serverless so /v1/resource goes to resourceHandler1.js. If v2 is backwards compatible then map /v2/resource to resourceHandler1.js. If it’s not then create resourceHandler2.js and map /v2/resource to that handler while keeping /v1/resource going to resourceHandler1.js. You’ll need to make both resourceHandler1.js and resourceHandler2.js work from the same underlying data set. This reduces duplication of code and data.
- This is basically the same as option 1 but put the handler lookup into a data structure in code that looks up the correct handler based on the version number. The advantage here is that you don’t need to have so many paths configured in the API gateway and you could even put the API version into the headers.
Finally, if you’re not committed to using REST then look at GraphQL.
Thanks for the response, @buggy! I really appreciate it. After posting here I also went back and found some other folks who I think were struggling with the same thing … I’m a bit surprised, it seems like a situation folks would often hit, and I would have thought there’d be more chatter about it.
I appreciate your ideas. I really like the GraphQL idea … next app I’m trying out that for sure. As for the two you added … yeah, it’s going to be painful, one way or the other … I’ll try to update this request with the path I took so that other folks can learn from my mistakes.
Personally, I would use aliases for this. one alias per version of your deployment.
You might want to look into this plugin: https://www.npmjs.com/package/serverless-aws-alias
Try this : serverless-ssm-version-tracker - npm
Helps keep track of the microservice versions. Updates on sls deploy.