Last summer, I wrote a blogpost about the migration of most of the microservices we have at Studyportals to Vue 3. The blogpost painted a picture of our approach and the progress made up till that point, but there was still a lot of work left to do. At the time, we found ourselves right in the middle of the migration process, with five microservices moved over and eleven more to go.
A couple of weeks ago, the last migration-related steps were wrapped up. With the fourteen-month-long process coming to an end, it was time for another blogpost. This blogpost is a continuation of the previous one: A Migration to Vue 3: part 1. It highlights the steps that we have taken since then and the things we have learnt from going through this entire process.
Time for a disclaimer: If you have not read the first blogpost yet, you might feel like you are missing key details to understanding the contents of this one. Questions might pop up such as: What is the microservice architecture that Studyportals uses? Why did they decide to migrate to Vue 3? And what approach did they define at the beginning? If you are looking for the answers to those questions, please check out the previous blogpost.
When the last blogpost was written, there was still plenty of work left to do. The steps that lay ahead of us can be labelled as follows:
- Migration of remaining microservices: With about one third of the microservices moved over, quite a bit of the actual migration work was still left to do.
- Clean-up: The final bits of work could be carried out only once all microservices were migrated.
- Retrospective: No project is complete without a retrospective, in which those involved reflect on the whole process to see what can be learnt from it.
The following sections will describe each of these steps in more detail.
First off, it is important to note that the overall plan, which had been defined at the beginning of the migration project, did not really change. Details were filled in along the way, such as the exact order in which microservices were migrated, who would take care of what, and additional smaller challenges that needed to be tackled, which we had initially not foreseen.
There were a few things that did change.
Of the five microservices which were migrated first, four were migrated by the same Scrum Team. This fact underlines the biggest difference between the way the migration started and the way it continued afterwards. By the end of the project, four Scrum Teams had been involved, each of them responsible for the migration of at least three microservices. Aside from the front-end and full-stack engineers (the people who work most with the microservices on a day-to-day basis) back-end engineers also chipped in.
It was important to involve several Scrum Teams and several disciplines, not only because that would make the workload more manageable, but also so that the knowledge of Vue 3 could be shared by a bigger group of people across the Engineering department. Moving forward, the migrated microservices would have to be maintained by those same people, after all.
The group of people included in the migration grew substantially in a short amount of time. This was possible by ensuring that the knowledge gained from the first migrated microservices was sufficiently shared. Those involved in the earlier migrations were included whenever the migration of a new application was kicked off, and they were also available for any questions or issues that came up along the way. Not much of the knowledge was put in writing, but a lot of tips and tricks were shared via word-of-mouth.
As the migration process progressed further, we looked for ways that newly migrated applications could benefit from the learning points of those microservices which had already been moved over. This resulted in some new tooling. One example of that was a Github repository set up with the barebone structure of a “Hello World” Vue 3 application. It contained configuration for Webpack, NPM, linting, and additional generic code that all microservices would need.
Furthermore, some NPM packages were built in-house, which brought added benefits such as ensuring that a microservice would have all the right dependencies installed and making the setup & unit testing of composition-API-based components easier.
Once the last microservice was moved over to Vue 3, it was time for the final clean-up. Other migrations might have depended on more “bridge” code, which provides functionality that serves the sole purpose of having two versions run side by side. In our case, the clean-up was a short and smooth process. The migration of the individual microservices was tackled in a proper way, and not many leftovers remained.
Throughout the migration process, we tried to have as few as possible Vue 2 and Vue 3 microservices running on the same pages, because the extra included kilobytes would negatively influence page speed. To some extent, a temporary negative impact was unavoidable. Once the Vue 2 framework / configuration was removed from our pages, we were happy to see the efforts of the clean-up back in our page performance metrics. Our pages were once again as fast as they had been before the migration.
With the clean-up taken care of, the migration reached its completion, but the project was not fully wrapped up yet. When working with Scrum, it’s good to take the time to reflect on every sprint; but the same is the case for bigger projects such as a year-long Vue migration. After all the time and work that was put in, it was worth it to organise a retrospective and see what could be learnt from the process.
For our retrospective, at least one representative of each Scrum Team was invited. Our goal was to extract useful takeaways that would help us for potential future migrations. We were happy with the way the migration to Vue 3 played out, but there is always room for improvement. The retrospective was structured as follows:
- A timeline was prepared, which created an overview of the steps that were taken from start to finish. Under the timeline, four tracks were added: Keep, Add, More, and Less.
- We observed the timeline and discussed together all the details that we could remember from the migration process. Any thoughts that popped up about what parts to keep, add, do more of, or do less of, were written on post-its and added to the respective tracks.
- By the time the timeline was enriched with any details we could think of, each of us voted for the three post-its which we thought to be most valuable (by dot voting).
- The emphasis that the votes created helped us to formulate three main takeaways.
The biggest points of improvement, which we identified during the retrospective, are the following:
- Do more elaborate planning / refinement up front. In our migration, some additional work was taken along, such as the upgrade from Webpack 4 to Webpack 5. Other aspects, such as automated testing and the bottlenecks some of the microservices would face, were not discussed in enough detail when planning the migration at the start. It could have helped us to allocate more time for planning at the start and to create a more detailed overview of what to include / exclude.
- Aim for a reasonable story / pull request size. The timeline visualised very well the different approaches that were taken with the migration of each microservice. The changes of some bigger microservices were combined into one big pull request, whereas the changes of other microservices were spread across many smaller pull requests. We concluded that, when choosing how to split up code changes, one should aim for the sweet spot of creating chunks of work that are manageable to be completed in a sprint and optimal for reviewing, while limiting overhead as much as possible.
- Approach migrations as a team effort. Especially in the second half of the migration, we did a better job at spreading the workload across the Engineering department. More people could have been involved sooner, to further accelerate the migration. It’s important to be pragmatic, yet critical with capacity planning for a project such as this one.
Overall, our migration to Vue 3 can be considered successful. Like any process, there were things that went well and things that could have gone better. We took the time to reflect on the whole project and defined takeaways which can help us with future migrations.
I hope that, after reading this blogpost and the previous vue-migration-related one, you have gotten useful insights that can help you tackle your migration in an effective way, whether it is to Vue 3 or something else entirely.