DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Navigating and Modernizing Legacy Codebases: A Developer's Guide to AI-Assisted Code Understanding
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • Build a Stateless Microservice With GitHub Copilot in VSCode
  • From Prompt to Running Microservice: ServiceBricks Step-By-Step

Trending

  • Strategies for Securing E-Commerce Applications
  • Designing AI Multi-Agent Systems in Java
  • Data Lake vs. Warehouse vs. Lakehouse vs. Mart: Choosing the Right Architecture for Your Business
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 1
  1. DZone
  2. Data Engineering
  3. Data
  4. Microservice Boundaries

Microservice Boundaries

What are the boundaries of microservices? How can you utilize them?

By 
Francisco Alvarez user avatar
Francisco Alvarez
DZone Core CORE ·
Aug. 26, 19 · Analysis
Likes (12)
Comment
Save
Tweet
Share
16.4K Views

Join the DZone community and get the full member experience.

Join For Free

Although working with microservices delivers many benefits, experience has shown that there are also some problems associated with their use. It is important to be aware of these issues so that their impact can be minimized.

One of these problems is getting right the boundaries of microservices. This has proved to be one of the most difficult tasks. It is not the first time I have found myself moving code from one service to another.

Establishing the Scope of Microservices

Admittedly, if each microservice had a single responsibility, this problem would not be as prevalent. However, defining the scope of single responsibility is not easy.

For the sake of the argument, let’s consider a payment service whose responsibility is to take payments on an e-commerce platform. Let’s suppose that, initially, there are only two payment methods, cards, and vouchers, and both methods are implemented in the same service. Is that ok? Is “taking payments” a single responsibility or should we create different services for each payment method? Why stop there? Why not create a different service for each type of card: Visa, Mastercard, American Express, etc.?

Knowing some of the future requirements could help make a more informed decision but normally that is a luxury that we do not have. Therefore, let’s imagine that, based on the information currently available, we decide to have a single service responsible for taking payments.

Changing Requirements

A few weeks down the line, new requirements come up to accept payments with Paypal and Apple Pay. Now it feels like implementing these new payment methods in the existing service will make the service grow too big and have “too many responsibilities”. In light of these new requirements, a decision is made to split the responsibility to take payments into different services according to the payment method.

Payments with Paypal and Apple Pay will be implemented in separate services, but what to do with the existing service that implements two different payment methods? Given that now the responsibility is defined at the payment method level, the original payment service is not consistent with this new approach. As a consequence, the service needs to be split into two new services.

Whereas in a monolithic application, the above change would amount to a relatively simple code refactoring, in a microservice architecture the code is to be moved into a new service, what would normally require: new code repository, new continuous integration/delivery pipeline, environment configuration, cloud computing/storage resources, etc.

Microservice Naming

As the scope of the services changes, even names get out of date. In our example, assuming that the original service was called ‘Payment’, the name became obsolete as soon as the responsibility was newly defined at the payment method level. In a platform where now there are services named ‘Paypal’ and ‘Apple Pay’, what does the old name ‘Payment’ represent?

Heuristic Approach to Microservice Boundaries

In an ever-changing environment, some services' responsibilities inevitably need to be redefined over time. There is no rule about how big or small a microservice should be. In the absence of an optimal solution, a heuristic approach based on experience seems to be our best bet.

Here are some suggestions:

  1. If some parts of the service change very frequently and others that barely do, that is a sign that the service could be split in two.
  2. Parts of the codebase that require specific testing or take longer to test are also better off in service of their own so that their lifecycle does not interfere with other elements of the application.
  3. Complex pieces of code should also have their service to avoid undesired interactions with other elements of the codebase that could cause bugs difficult to identify.
  4. Code to access external resources like databases or queues should be encapsulated in its service too: you would not want to have to configure your local environment with those external resources just to be able to start the service and then use some functionality completely unrelated to the external resources.

A Real-Life Case

If the above made-up example about the Payment service does not feel appealing enough, here’s a real case.

Eurostar has been selling train tickets between London and other European capitals for 25 years. About three years ago, I worked with them to turn their monolith into microservice architecture, so we developed new services like ‘search’, ‘checkout’, etc. Clearly, in the context of Eurostar, the terms ‘search’ and ‘checkout’ referred to its only product, the one that had been sold for 25 years: train tickets.

Soon after the new microservices were completed, Eurostar made a strategic decision to become a travel agency and sell hotel accommodation and package holidays in addition to train tickets. New services were created: ‘hotel-search’, ‘hotel-checkout’, etc., rendering the names of the existing services inadequate and questioning their scope by posing questions like, do we need a common checkout service or should we keep them separate?

The morale is that businesses change and, as a consequence, services need to be revisited and refactored.

microservice

Published at DZone with permission of Francisco Alvarez, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Navigating and Modernizing Legacy Codebases: A Developer's Guide to AI-Assisted Code Understanding
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • Build a Stateless Microservice With GitHub Copilot in VSCode
  • From Prompt to Running Microservice: ServiceBricks Step-By-Step

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!