Modular services are composable building blocks for rapid application in new and varied business needs and solution contexts. A modular approach promotes accelerated delivery of value (less components to build and release), lower overall operational footprint (as we do not rebuild the same functionality multiple times) and lower operating costs (smaller ops teams, licensing etc)

Thus the goal is for the modular components to be used in newer business solution contexts without re-building the necessary foundations each time. But simply making things modular does not guarantee reuse and not all reuse leads to autonomy and speed
How you get modular matters
Modular service design is not a new concept, we have been doing modules within our standalone applications and also have learned to do this for integrated applications we engineered. However the process of determining the modules (i.e. module heuristics) have been guided by technology systems, projects or size.
Picking the incorrect module leads to chattiness (when two cohesive modules are decoupled), explicit dependency (as part of a whole is owned by someone else), implicit dependency (shared module) etc. Poor module design hampers reuse and fails to drive ROI due to silos that replicate or improper reused that couple teams over time (worse been hidden or implicit coupling)
Poor modular design can happen when we attempt to build strategic modules in a tactical project context as we orient to meet project specific solution needs vs a wider business strategy. Good module design starts top-down and uses business boundaries and business capabilities for module design to balance cohesive elements vs external decoupled elements

Good module design also requires ownership and product centric module (interface) life-cycle management to decouple consumers from module evolution leading to higher ROI
Module Design nHeuristics

When designing modular APIs we may follow some process (actively or passively), some of these processes follow a deliberate set of principles and style while others may be accidental
Listed below are a set of heuristics based on my observations and experience across various enterprise IT landscapes across various industries. Observing the artefacts produced by these design choices over a long time-period (2-3 years) has lead me to factor in better choices when doing a solution design. Also, I am keen to do a longitudinal study and measure key indicators such as reuse, time to delivery and operating costs across industries to improve the accuracy of the recommendations below
Our observations show often we design modules consciously applying deliberate design choices, however we do see pattern #1 and #3 applied quite regularly as the default choice. This means we are still deploying solutions with modules aligned to a project need(tactical) or some abstract concept. We also see #6 become popular as heuristic with microservices and functions leading to very chatty and fine-grained service modules
We highly recommend #9 which applies business and functional grouping as key factors for module design and this allows us to build the most optimal internally cohesive and externally pluggable architecture.
List of heuristics
- Accidental: When no deliberate module design choice exists and it happens accidentally
- Monolithic: A single module which implements all the functional elements as internal sub-modules which interact tightly with each other. Single deployment unit and runtime
- Project monolith: A single project oriented multi-functional module that operates very tactical solution in internal sub-modules and may interact with other modules (from other projects etc) via an interface
- System oriented: When the core systems determine the modular APIs in our ecosystem and also influence their interface and model
- Application influenced: When a legacy application (MVC) architecture influences the API modules we build. The legacy MVC application(s) could be composed of sub-modules internally but the API exposes these as a single functional element
- Size based: When a module is a single function component designed to limit its size and presents a service (e.g microservice)
- Business function based: A single enterprise-wide function based module (e.g. Policy API that does policies for all lines of business)
- Business domain oriented: When the module contains all the functional elements for a single business domain
- Business domain and function based: When the module contains only some specific functionality for a business domain and co-exists with other modules from the same business domain with different functionality

Oriented to Business capabilities based module design
Of the various module design heuristics we find #9 as the most effective patterns for delivering modules such that they yield the best balance between encapsulation (leading to autonomy & flexibility over time) and reuse (from the right functional distinction by business group)

The way organisations can orient to this design pattern is by starting with a strategic business oriented design (such as strategic DDD) and then iterating over specific domains to determine the scaffolding modules (placeholders). Then when project funding arrives they can help build the details of the modules and reap the benefits while aligning to a strategic enterprise integration module architecture
How do the gains come over time?
The key to upfront design is to invest upfront in strategic architecture. This requires 4-8 weeks of analysis of the big picture and the key building blocks or modules. After this an iterative design approach with projects delivering key domain services (or an initial project delivering all domain services) can lead to subsequent projects reusing existing APIs and consumer teams working with businesses to deliver specific solutions by aggregating these domain APIs

Governance is key here as projects can operate in silos and we all love to re-invent the wheel, chassis, transmission etc. Having the strategic enterprise architecture engaged with solution delivery is key and it requires an API strategy owner
Breaking Down the Investment:
- Legacy SOA and RPC-Style Services: They might seem cost-effective at a project level but over time these services cannot extend to other contexts
- Basic RESTful Patterns: These can be simple to build initially but as more consumers come on board these services are duplicated without business context. Modules are tech oriented and very fine-grained. Also they can be quite chatty given low cohesiveness across these naive apis
- Business Domain / DDD based APIs: They identify business resources and states and lead to better module granularity. This balances cohesion & coupling concerns well
Conclusion:
Modular architecture is the best for software engineering as it lets us build reusable artefacts. In distributed systems design we want to apply this principle for higher return on investment from our projects building APIs. We cannot do this if we pick the incorrect module design heuristics for distributed system design as only options like business domain based modules have the long term autonomy and advantage
Sadly this practice requires upfront funding as project / solution based funding model tends to drive consumer needs into core modules leading to coupling over time. We recommend strategic domain design before jumping into the deep end of API design for an end-to-end solution as big picture architecture can help provide a well considered scaffolding vs an emergent big ball of mud scaffolding