Reducing insider trading in a microservice architecture

microservice architecture   architecting   loose coupling   design-time coupling  

During a workshop I taught this week, we had an interesting discussion about a common microservice architecture design problem:

The doSomething() operation, which is implemented by Foo Service, needs to get data from numerous services including Bar Service and Baz Service in order to respond to a request. Getting the data via their APIs seems lot of work. Why can’t it just query the databases directly?

Here’s my answer:

Read on to learn more.

Services must be loosely design-time coupled

A defining characteristic of the microservice architecture is that services are loosely design-time coupled. Consequently, services should not share their databases with other services since it results in type design-time coupling. Service must, instead, collaborate via their APIs.

APIs don’t guarantee loose design-time coupling

You might be tempted to think that as long as services communicate via their APIs, they are loosely design-time coupled. Foo Service could, for example, query each of the other services: ie. invoke getBarInfo(), getBazInfo(), etc. Alternatively, it could use the CQRS pattern The problem with both of these approaches is that they don’t guarantee loose design-time coupling. A service API might simply expose its database schema through its API.

It’s insider trading

One service retrieving data from another service can sometimes resemble the Inside Trading code smell. The service behaves like a class (or modules) that accesses the internal data of another class (or module). And, just like Inside Trading between classes, it can lead to a tightly coupled design that is difficult to understand, maintain, and evolve.

Design services to look like icebergs

A service should resemble an iceberg. Its API should encapsulate the implementation details. We can increase encapsulation in the above example by refactoring the doSomething() operation and moving the logic that uses some other service’s data from the Foo Service into the other service. The doSomething() operation then invokes an operation on each of the services that executes the service-specific logic. It would, for example, invoke doSomethingBar() on the Bar Service and doSomethingBaz() on the Baz Service. Such an approach can significantly increase encapsulation and reduce design-time coupling.

Applying the idea to takeout burritos

In my QConPlus 2021: Takeout burritos and minimizing design-time coupling in a microservice architecture talk, I applied this idea to the Order Service and Restaurant Service example. Originally, the Order Service’s createOrder() operation retrieving a restaurant’s menu to validate the line items and compute the Order’s subtotal. The drawback of this approach is that the Order Service is tightly coupled to the Restaurant Service: any change to the structure of MenuItem in the Restaurant Service would require a lockstep change in the Order Service. The solution was to reduce design-time coupling by moving responsibility for knowing the OrderLineItems and computing the Order’s subtotal into the Restaurant Service. The Restaurant Service simply passed the Order subtotal to the Order Service.

Need help with accelerating software delivery?

I’m available to help your organization improve agility and competitiveness through better software architecture: training workshops, architecture reviews, etc.

Learn more about how I can help


microservice architecture   architecting   loose coupling   design-time coupling  


Copyright © 2024 Chris Richardson • All rights reserved • Supported by Kong.

About Microservices.io

Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns.

ASK CHRIS

?

Got a question about microservices?

Fill in this form. If I can, I'll write a blog post that answers your question.

NEED HELP?

I help organizations improve agility and competitiveness through better software architecture.

Learn more about my consulting engagements, and training workshops.

LEARN about microservices

Chris offers numerous other resources for learning the microservice architecture.

Get the book: Microservices Patterns

Read Chris Richardson's book:

Example microservices applications

Want to see an example? Check out Chris Richardson's example applications. See code

Virtual bootcamp: Distributed data patterns in a microservice architecture

My virtual bootcamp, distributed data patterns in a microservice architecture, is now open for enrollment!

It covers the key distributed data management patterns including Saga, API Composition, and CQRS.

It consists of video lectures, code labs, and a weekly ask-me-anything video conference repeated in multiple timezones.

The regular price is $395/person but use coupon NPXJKULI to sign up for $95 (valid until December 25th, 2024). There are deeper discounts for buying multiple seats.

Learn more

Learn how to create a service template and microservice chassis

Take a look at my Manning LiveProject that teaches you how to develop a service template and microservice chassis.

Signup for the newsletter


BUILD microservices

Ready to start using the microservice architecture?

Consulting services

Engage Chris to create a microservices adoption roadmap and help you define your microservice architecture,


The Eventuate platform

Use the Eventuate.io platform to tackle distributed data management challenges in your microservices architecture.

Eventuate is Chris's latest startup. It makes it easy to use the Saga pattern to manage transactions and the CQRS pattern to implement queries.


Join the microservices google group