8 Essential Principles for Designing a Business Middle Platform
This article outlines eight core principles for designing a business middle platform, covering service loose coupling, dependency management, design guidelines, naming, granularity, statelessness, operation design, and constraint rules to ensure scalable, maintainable, and business‑aligned services.
Business middle platform (or “mid‑platform”) is a living component that encapsulates business logic, persists domain data, creates value, and evolves as the business grows. Its design follows eight core principles.
01 Service Loose‑Coupling Principle
Interface‑oriented implementation – Each service is built strictly to its contract (interface). Consumers depend only on the interface, not on a concrete implementation, so provider changes are transparent.
Asynchronous event decoupling – Services exchange events through an asynchronous message queue. Producers and consumers do not need to be online simultaneously, which removes real‑time processing constraints.
Provider location decoupling – Consumers discover providers via a service registry (e.g., Eureka, Consul) instead of hard‑coding IP/port. The registry also supplies load‑balancing and fail‑over.
Version loose coupling – Clients must not rely on a specific contract version. Service contracts must remain backward compatible when upgraded.
02 Service Dependency Principle
Valuable domain model – Services should reflect the enterprise’s core business goals and domain concepts.
Minimal inter‑service dependency – Aim for high cohesion within a service and low coupling between services. Identify generic capabilities and expose them as independent services.
Capability entities have hierarchy – Separate interface entities from capability entities and organise them in a hierarchical structure (e.g., base capability → extended capability).
Delay technical component dependencies – Avoid bundling unrelated technical components. Use delayed binding so a dependency is introduced only at the point of use.
03 Service Design Principles
Optimize remote calls – Choose synchronous or asynchronous invocation based on latency, consistency, and throughput requirements.
Eliminate redundant data – Remove fields that clients never consume to reduce payload size and parsing complexity.
Design coarse‑grained interfaces – Map one service interface to a complete use case or business scenario; this reduces call frequency and learning cost.
Design generic service interfaces – Use simple, widely supported data types (e.g., primitives, JSON) so the same service can serve multiple applications.
Isolate internal changes – Hide internal domain models behind DTOs or view objects; internal refactoring does not force client changes.
Service‑first contract definition – Define the API contract (e.g., OpenAPI/Swagger) before implementation to enforce clear expectations on both sides.
Downward compatibility – Preserve contract stability after release; any upgrade must maintain backward compatibility or provide a controlled migration path.
04 Service Naming Principle
Use business‑domain nouns for service names (e.g., OrderService) and verbs for operations (e.g., createOrder). Prefer domain concepts over technical terms.
05 Service Granularity Principle
A service should be cohesive and complete, capable of fulfilling a single responsibility independently, even if internally it consists of several tightly related code blocks.
06 Stateless Service Principle
Statelessness is essential for scalability and high availability. Services must not retain client‑specific state between requests; any required state should be stored in external stores (e.g., databases, caches).
07 Service Operation Design Principles
Important services must not depend on non‑important services.
All service calls must specify a timeout to avoid indefinite blocking.
Call results are limited to three states: success , failure , or unknown .
Prefer asynchronous calls when possible to improve responsiveness and reduce coupling.
When splitting a system, target a team size of 3‑8 developers per service boundary.
Start with the data‑service layer because of its high reusability.
Design services without single points of failure; use redundancy and circuit‑breaker patterns.
Apply the fast‑fail principle: return immediately on error to prevent performance degradation.
For high‑load scenarios, shorten call chains or pre‑warm services.
Avoid providing the same capability through multiple service units.
Enforce backward compatibility; if impossible, require a controlled upgrade mechanism for consumers.
Organisational structures should adapt to architectural changes (e.g., Conway’s law).
Separate read and write services, and core from non‑core services, to improve stability.
Security considerations (authentication, authorization, data protection) must be integrated into service design.
Static resources can be “service‑ified” to separate them from dynamic resources and improve performance.
Instrument outer‑layer systems (metrics, tracing) for fine‑grained capacity and performance management.
Encapsulate common business rules of each domain as reusable services.
08 Service Constraint Principles
Higher‑level services may depend on lower‑level services, but not vice‑versa.
Peer services may call each other unidirectionally; circular dependencies are prohibited.
Simplicity is preferred – keep designs as simple as possible while meeting requirements.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
