<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui" -->

---
title: Decomposing a Monolith into Microservices with Call...
description: A concrete walkthrough decomposes a Java EE 7 monolith (the CoolStore e-commerce app) into three microservices—Catalog, Cart, and Order—using rgctl, a static...
canonical: https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Decomposing a Monolith into Microservices with Call Graph Analysis | daily.dev
og:description: A concrete walkthrough decomposes a Java EE 7 monolith (the CoolStore e-commerce app) into three microservices—Catalog, Cart, and Order—using rgctl, a static...
og:url: https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui
og:image: https://api.daily.dev/og/posts/BslHwBQuI.png
og:image:alt: Decomposing a Monolith into Microservices with Call Graph Analysis
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Decomposing a Monolith into Microservices with Call Graph Analysis

**[Shaaf](https://daily.dev/sources/shaaf)** · 17 min read · 1 upvotes · 0 comments

## Summary

A concrete walkthrough decomposes a Java EE 7 monolith (the CoolStore e-commerce app) into three microservices—Catalog, Cart, and Order—using rgctl, a static call-graph analysis tool. Community detection (label propagation) identifies natural code clusters, blast radius scoring quantifies coupling at proposed service boundaries, and CPG field mutation tracking reveals shared mutable state (like the ShoppingCart object) that should not be split further. Specific coupling problems are worked through: the Transformers utility class split across three services, PromoService spanning two communities, and a synchronous cross-service call from cart to catalog. The piece ends with CI policy guardrails to prevent boundary violations from creeping back in.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://shaaf.dev/post/decomposing-a-monolith-into-microservices-with-call-graph-analysis>

## Questions this post answers

### How do you use blast radius analysis to decide where to cut a monolith into microservices?

Blast radius measures how many upstream functions break if you change a given function, and cross-service candidate calls with low, contained blast radius scores make safer service boundaries. In one Java EE decomposition, message-driven bean handlers scored 0.0 blast radius (zero upstream callers), confirming they could be safely converted from JMS to reactive messaging without breaking other code.

_Developers planning a microservices split can find similar architecture breakdowns and tooling deep dives on daily.dev._

### How do you handle a shared utility class like Transformers when splitting a monolith into microservices?

Split the class method-by-method based on which domain model each method depends on, rather than moving it wholesale. In one case, toProduct (blast radius 40.7) moved into the catalog service since it depends on CatalogItemEntity and Product, shoppingCartToJson moved into the cart service, and jsonToOrder moved into the order service, since each method only referenced models owned by its target service.

_Teams untangling shared code during a service split can track patterns like this via daily.dev._

### Why shouldn't you split shopping cart pricing, shipping, and promotions logic into separate microservices?

Because they share dense mutable state that makes them inseparable at deployment time. Field mutation analysis on a ShoppingCart object showed six fields (cartTotal, shippingTotal, cartItemPromoSavings, and others) mutated by functions spread across three different code communities including PromoService and ShippingService, meaning a split would force synchronous round-trips for every pricing operation.

_Anyone weighing service boundaries around shared state can keep up with architecture case studies on daily.dev._

## Similar posts on daily.dev

- [Migrating an application to Quarkus: A Graph-Driven Approach with rgctl](https://daily.dev/posts/migrating-an-application-to-quarkus-a-graph-driven-approach-with-rgctl-m9ydyypwb) · Shaaf · 0 upvotes · 0 comments
- [Monolith to Service Architecture](https://daily.dev/posts/monolith-to-service-architecture-2izyvqort) · System Design Codex · 102 upvotes · 4 comments
- [How to Move from Monolith to a Service Based Architecture](https://daily.dev/posts/how-to-move-from-monolith-to-a-service-based-architecture-8wr0lttmy) · System Design Codex · 74 upvotes · 3 comments
- [The Distributed Monolith Trap \(And How to Escape It\)](https://daily.dev/posts/the-distributed-monolith-trap-and-how-to-escape-it--am21bxegj) · Three Dots Labs · 78 upvotes · 3 comments

---

Tags: [#java](https://daily.dev/tags/java), [#architecture](https://daily.dev/tags/architecture), [#microservices](https://daily.dev/tags/microservices)

[View this post on daily.dev](https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Decomposing a Monolith into Microservices with Call Graph Analysis","url":"https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui"},"datePublished":"2026-09-01T17:46:08.175Z","dateModified":"2026-09-01T17:52:34.321Z","description":"A concrete walkthrough decomposes a Java EE 7 monolith (the CoolStore e-commerce app) into three microservices—Catalog, Cart, and Order—using rgctl, a static...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f7915b14a10a216285ec688a1c359c3a?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f7915b14a10a216285ec688a1c359c3a?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Shaaf","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Shaaf","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/0b296c189bd840d99decdb5078460675","url":"https://daily.dev/sources/shaaf"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"java,architecture,microservices","timeRequired":"PT17M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Shaaf","item":"https://daily.dev/sources/shaaf"},{"@type":"ListItem","position":3,"name":"Decomposing a Monolith into Microservices with Call Graph Analysis"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/decomposing-a-monolith-into-microservices-with-call-graph-analysis-bslhwbqui#faq","mainEntity":[{"@type":"Question","name":"How do you use blast radius analysis to decide where to cut a monolith into microservices?","acceptedAnswer":{"@type":"Answer","text":"Blast radius measures how many upstream functions break if you change a given function, and cross-service candidate calls with low, contained blast radius scores make safer service boundaries. In one Java EE decomposition, message-driven bean handlers scored 0.0 blast radius (zero upstream callers), confirming they could be safely converted from JMS to reactive messaging without breaking other code. Developers planning a microservices split can find similar architecture breakdowns and tooling deep dives on daily.dev."}},{"@type":"Question","name":"How do you handle a shared utility class like Transformers when splitting a monolith into microservices?","acceptedAnswer":{"@type":"Answer","text":"Split the class method-by-method based on which domain model each method depends on, rather than moving it wholesale. In one case, toProduct (blast radius 40.7) moved into the catalog service since it depends on CatalogItemEntity and Product, shoppingCartToJson moved into the cart service, and jsonToOrder moved into the order service, since each method only referenced models owned by its target service. Teams untangling shared code during a service split can track patterns like this via daily.dev."}},{"@type":"Question","name":"Why shouldn't you split shopping cart pricing, shipping, and promotions logic into separate microservices?","acceptedAnswer":{"@type":"Answer","text":"Because they share dense mutable state that makes them inseparable at deployment time. Field mutation analysis on a ShoppingCart object showed six fields (cartTotal, shippingTotal, cartItemPromoSavings, and others) mutated by functions spread across three different code communities including PromoService and ShippingService, meaning a split would force synchronous round-trips for every pricing operation. Anyone weighing service boundaries around shared state can keep up with architecture case studies on daily.dev."}}]}
```

