Contract tests

Currently, microservices are one of the most common patterns in software development. New projects are still designed and implemented with microservices architecture. Not only huge projects like Amazon, Uber, and Netflix are using this technology. In modern, much smaller projects, microservices are eagerly chosen.

So, imagine you’re a developer involved in an app platform project. There are some microservices, and every small team is working on its own microservice. You and your team are responsible for delivering a user service. It’s just a microservice which stores information about users and provides authentication. Okay, so let’s go. It was easy, and the first version is ready. There are some endpoints exposed which allow other services to fetch information about the users. And one day, the change request appears. You need to change the user object structure.

The problem 

It’s the beginning of pain. Once you change the structure, you need to update the other teams to make sure you won’t break their services. Because they’re using your data, some tasks are still blocked. You are waiting for confirmation and responses, and the product owner is still waiting for the requested change.


How should you deal with it? Of course, we can do integration testing between each microservice. However,  that requires a lot of effort, separate environments (and maintaining them), and it’s generally complicated. In my opinion, the best solution for this case is to use contract tests. 

Solution 

Contract tests allow us to create pacts between our services and store them in one place. They’re easily accessible for all involved teams. The next step is to add a contract test to our continuous integration (CI) flow. Then we’re sure that our microservice will expose and fetch the correct data from other microservices. 

How does it work?

If you are a consumer, you need to implement consumer contracts. All you need to do is just write tests, and then mock requests structures and expected responses. The library which I recommended, Pact.io, will do the rest of the work for you. It will create a mock server and verify your requests against the expected request which you defined. When verification is completed, then pact files are generated. You can share them with other teams. All they need to do is to run them as providers. The library will start the real server and verify responses against expected. If they’re the same, the verification is done! Then, pacts can be published to pact broker. Now, both microservices can be deployed safely. 

Why is it safe? 

In the case when you are a provider of some data to other services and you unconsciously change the data that is used by another microservice, you won’t break it. That’s because tests won’t pass. You don’t need to think about which microservices are using your data and keep all the teams informed because everything is in the pact broker. 

Disadvantages?

I’m not saying that writing contract tests is super quick. It isn’t. But it’s definitely faster and more efficient than the other approaches I mentioned before. As a reminder, I mentioned that it improves collaboration between teams but doesn’t solve all of the issues. Sometimes, you’ll need to wait for pacts verification by providers which could block you. There’s no perfect solution in this case. The first impression with contacts could be tricky because setup is not the easiest, but in the case of Pact.io, it’s quite well documented. 

Summary

It saved me several times from breaking other services. At the beginning, I didn’t realize how powerful it is. But when project growth happens and change requests come, in my opinion, it’s the best way to avoid stress and work on microservices with confidence! 

Sources

  1. Who is using microservices https://microservices.io/articles/whoisusingmicroservices.html
  2. https://docs.pact.io/