Legacy software modernization is a constant struggle. There's the struggle to maintain the application itself as...
the technical world around it changes. Developers want to work on the latest thing, so there's also a struggle with retaining developers with the skills and desire to work with older technology. Microservices can breathe new life into those legacy systems by providing new functionality that can be used in older technology without rewriting anything.
Microservices provide a way of retrieving and processing data that is external to the application itself. All communication between the legacy software and the microservice is via JSON, meaning that the legacy application using the data and the microservice itself share only this common communication protocol. Therefore, the microservice can be written in any language that is convenient and appropriate for the job to be done. Need to enhance an ASP Classic site with business logic best written in F#? Use a microservice to do the processing and return the results. Do you have a routine already written and debugged in C# that a Cobol program needs to use? Microservices are your answer.
Because these services can be written in any language that is appropriate, they also serve to keep your developers happy. Few developers want to maintain legacy applications, but it is easier to persuade them if they also can get some experience in the latest programming language and new infrastructures, without being encumbered by pre-existing infrastructure.
Microservices are also an opportunity to "spread the love" and get others involved. Because there are such strong module boundaries between the service and the legacy application, the developer writing the service need not be on the same team as the one handling the legacy software modernization. With appropriate requirements written, a microservice is the perfect project to outsource to low-cost development overseas. It has specific deliverable requirements, is a stand-alone system and can be developed in a virtual vacuum, and should be plug-and-play so it can be replaced as necessary.
The biggest ROI in microservices in relation to legacy software modernization is removing the need (or desire) to rewrite the legacy application. Using this new approach not only enables enhancements to the legacy code, but it also removes the pressure to rewrite that application from scratch -- which is often an expensive choice.
Even if the decision is made to rewrite the legacy application, microservices provide a way to do so slowly and predictably without violating any service-level agreements. Small steps can be made to chip away at the existing application, replacing certain functionality with microservices. In this way, one can slowly decrease the size of the legacy application, thus decreasing the time requirement for the rewrite.
With all of these advantages to using microservices, there are still some points to be wary of. For example, the approach can be overused. Microservices are, by definition, small, but they need to have the full support of production roll-out processes and testing. Though the effort necessary to achieve these goals is small, it does exist and cannot be ignored. If you try to enhance an existing application with too many different microservices, you could be trading one problem for another.
Another issue is performance. Any time service boundaries are crossed, system performance takes a hit. Making the microservice calls asynchronous can make the application appear to be more responsive, but is more difficult (or impossible) to code in legacy technologies. When turning to microservices as a solution to enhancing an existing feature of a legacy application, it should be assumed that the performance of that feature will decrease. What is an acceptable decrease is up to the business to decide. If you are implementing a new feature in a legacy application via microservices, it is an easier road because there are no previous performance expectations by the user.
All this assumes, of course, that the legacy language has certain attributes. For example, we assume the language has the ability to make Web service calls. Although the older the language, the more difficult this is, I am unaware of any language that cannot make use of Web service calls in some way.
Asynchronous calls are also necessary. Any synchronous call to a Web service is a recipe for disaster because users will soon be calling to complain about system performance. Making asynchronous calls requires some sort of multithreading support, which may be difficult to find (I'm looking at you, COBOL). Ensure these basic capabilities are available before launching yourself into the microservices world.
Using refactoring to breathe new life into legacy software
Increasing cloud app efficiency via microservices
Is BPM a viable solution for app modernization?