YTGI Monolith to Microservices

Top 5 Reasons to Use Microservices

Microservices are an architectural approach in which a complex application is broken down into smaller, independently deployable, or modular services. Each focused on specific business capabilities. A complex application does not have to be complicated; a user portal is a fine example. Here is a blog post with a summary describing microservices.

There are many reasons to use Microservices in your business. If you or others in your company are not convinced whether to head down the Microservice path, I’ve compiled my Top 5 list of reasons you should consider.

Ability to deploy changes quickly

Microservices promote flexibility in development and deployment. Each service can be developed, deployed, and updated independently, enabling teams to work on different services simultaneously without affecting others. This agility accelerates the development cycle, facilitates continuous delivery, and allows you to respond quickly to changing business requirements.

A Microservice should be designed to comprise only a small, contained piece of business functionality. This matters because the application has a smaller scope of functionality. If you have a “Customer” microservice, it will only change when there are new requirements for how a customer is saved or displayed.

Cherry Picking

Here’s a real-life example: Many web services developed over the years have hundreds of endpoints covering customers, invoices, policies, shipments, enrollments, bill pay, etc. What often happens is that developers are working on changes in multiple areas. So when a developer finishes their changes to the customer, they may be unable to deploy because other changes to invoices and bill pay are not yet finished and tested. This ties your hands until all the changes are complete before you can release them.

Experienced developers may disagree because there is a way to only promote the changes to the customer code to the branch that will be released. This method is called “Cherry-picking.” The DevOps team can see that functionality is complete and only merge that code into the branch that will be released next.

The more manual steps in a process, the more prone it is to errors.

I don’t typically recommend this method because it has too many manual steps. The more manual steps in a process, the more prone it is to errors.

Avoiding Conflicting Changes

I’ve also run into the scenario where Developer 1 finishes their code, which merges to the branch to deploy to the QA server. Developer 2 pulls the latest code to work on a different change. Developer 2 finds a cool function and uses it in their code. Developer 2 doesn’t realize that this function was just added by Developer 1. During testing, Developer 1’s changes were rejected, and they had to return for more work. Developer 2 pushes their code to QA, and it passes. When DevOps cherry-picks Developer 1’s code to go to the release branch, it won’t work because it depends on Developer 2’s code, which is back in development.

This scenario may sound like an edge case, which it may be. However, it happens often enough in a busy shop that a different method, Microservices, can eliminate it. It also has the side effect of eliminating the “Cherry picking” manual process.

Automated Testing is Easier

One key factor in a Microservice is that the development teams must provide Unit and Contract Tests for all their code. This is easier to mandate and catch in a smaller Microservice project than in a large monolithic API. I mentioned Unit and Contract Tests. However, different organizations implement many other types of tests. I see these two as the essential requirements for having enough confidence to move forward with automated deployments, CI/CD, discussed below.

Essential Test Suites

Unit Tests: These tests are for small independent pieces of functionality. An example would be a function that takes a piece of data and converts it to Proper Case. In a Test Driven Development environment (TDD), a developer would write a plethora of unit tests where they pass in the word “jack” and check that it returns the word “Jack.” Then, pass in the word “Jack” and ensure it still returns “Jack.” The developer will write several, if not dozens, of these tests, all failing until they finish writing the function.

Contract Tests: The web has several definitions of contract tests. YTGI uses the definition of a test that runs through one path of the code from beginning to end—or as much as possible. Getting at least 80% code coverage may take many contract tests. Code coverage means the percentage of the code that was executed using a group of tests. It’s not practical to shoot for 100% code coverage because some code paths, like exception handling, are challenging to reproduce in a test, and they fall under the heading of diminishing returns.

Typically, when a developer checks their code in, there is a code review. If no issues are found, their changes may be approved to be merged into the branch, where a build server will attempt to compile the code and run the Unit and Contract tests. If any of the tests fail or the code coverage is less than 80%, it must go back to the developer immediately to resolve it. This system results in automated testing that will catch many problems before they even get to the QA team, meaning less chance of code circling back from QA to development.

Reduce bugs that make it to Production

The automated testing will help reduce the number of bugs that move from the development team to the QA team. This has a domino effect in that the QA team finds fewer issues overall, allowing them to concentrate on testing the application instead of nitpicking many items they find.

The QA team will be able to ensure that the changes meet the Acceptance Criteria defined by the business users. As the development team matures with more microservices, the QA team members may have some extra time to pursue their automated testing, usually in Integration tests.

Integration Tests: These tests are often run against the application deployed in a test environment. The main difference between an Integration Test and a Contract Test is that Contract Tests will use mock/or fake data. An Integration Test will be in the test environment and will use live test data from the database.

Automated Integration Tests are great because they often uncover issues in the code caused by situations in the data that the developer did not anticipate in their Contract and Unit Tests. For instance, a developer may not think to test where the customer’s last name is blank. Since this situation exists in real life, Integration Tests may uncover issues that can be addressed in the code and added to the Contract Test suite.

Scalability

YTGI Microservice Scalability

Microservices allow you to scale different components of your application independently. Instead of scaling the entire monolithic application, you can scale specific services based on demand. This elasticity enables you to optimize resource utilization and handle fluctuations in user traffic more efficiently.

When a new microservice is deployed, the server it resides on should be behind a load balancer, even if you don’t expect to have lots of traffic right away. You’ll want a friendly DNS name that won’t change to access your APIs.

This depends on your deployment method. If you deploy them to look like sub-services in an API Management Plan, then they may appear this way to the end user:

  • api.mycompany.com/api/customers/v1
  • api.mycompany.com/api/invoices/v1
  • api.mycompany.com/api/shipments/v1

After a few months, it was found that the shipments API was very busy. It was so busy that it was slowing down other server services. In the above example, where api.mycompany.com is directed directly to a server, moving that API alone to another server will be challenging. At that time, a load balancer must be implemented after the fact and the subdomain migrated to it. You can head these problems off before they occur by implementing the subdomain to a load balancer in the beginning and having all the API routes go to one server in the beginning.

If you implement each microservice as a subdomain, such as:

  • customer-api.mycompany.com/api/customers/v1
  • invoice-api.mycompany.com/api/invoices/v1
  • shipment-api.mycompany.com/api/shipments/v1

Then, each can be moved to another server independently without a load balancer; however, if you want to double up the servers for High Availability (HA), a load balancer is required with either implementation.

Easier Continuous Integration / Continuous Deployment (CI/CD)

CI/CD often seems like an unattainable goal for many organizations. Implementing microservices opens an easier path to achieving your CI/CD goals. The ability to release changes as often as needed is wide open.

…with automated testing your organization can be confident in the release code, which will automate the production releases.

Combined with the Automated Testing discussed above, your organization can be confident in the release code, which will automate the production releases. There is typically one manual step in which a DevOps engineer merges the code from the branch used for testing to a “release” branch. The automated deployment servers will see the change and deploy at the preprogrammed time.

Summary

After writing software for decades, I sincerely believe that these top 5 reasons to use microservices are enough to convince anyone to move forward. Another benefit that almost made the top 5 is “Technology Diversity.” Each microservice in your organization could be written in a different programming language! If you have diverse teams that use different technologies, a microservice can be implemented in any of them. These reasons highlight how microservices can empower your business by promoting agility, scalability, resilience, maintainability, and technology diversity. Evaluating your specific business needs and technical requirements before adopting microservices is essential to ensure a successful implementation.

author avatar
Jack Yasgar
Jack Yasgar’s career as a software engineer and architect spans more than two decades. Specializing in software integration projects.