We grow our systems a slice of functionality at a time. As the code scales up, the only way we can continue to understand and maintain it is by structuring the functionality into objects, objects into packages, packages into programs, and programs into systems. We use two principal heuristics to guide this structuring:
Separation of concerns
When we have to change the behavior of a system, we want to change as little code as possible. For example, code to unpack messages from an Internet standard protocol will not change for the same reasons as business code that interprets those messages, so we partition the two concepts into different packages.
Higher levels of abstraction
The only way for humans to deal with complexity is to avoid it, by working at higher levels of abstraction. We can get more done if we program by combining components of useful functionality rather than manipulating variables and control flow; that’s why most people order food from a menu in terms of dishes, rather than detail the recipes used to create them.
SOLID principle helps us achieve great results designing classes, components and systems
Monolithic Architecture



Conventions
| group-id | com.org.lob | ||
| artifact-id | lob-project-{market|subproject}-apis|services|ui-{short-description} | ||
| package | com.org.lob.config, com.org.lob.domain1, com.org.lob.domain2 |
Note : Project | Subproject ==> Three letter acronym
Monolithic package structure

Microservices Architecture

Best way to categorize a service as microservice, is that it would be exposing only one interface for an entity (Order for example), some folks even go to an extent of writing separate deployable units for each of CRUD operations.
So a microservice may expose CRUD operations for order entity Using REST as follows
| End Point | Details |
|---|---|
| PUT /api/v1/order/{id} | Create or replace an order |
| POST /api/v1/order | Create or update an order |
| GET /api/v1/order | Get all orders |
| DELETE /api/v1/order | Delete an order |
| POST /api/v1/order/{id}/execute | Executes an order |
A separate deployable unit would expose order operations over kafka for example ( or over MQ for example )
A microservice works over only one domain, and exposes only one interface and may potentially interact with 1 or more internal or external interfaces.

Conventions
| group-id | com.org.lob | ||
| artifact-id | lob-proj-{market|subproject}-{api|mq-consumer|kafka-consumer|grpc|ui|job}-short-description | ||
| package | com.org.lob.config, com.org.lob.project, com.org.lob.othersystem |
Each microservice should be structured into layers as shown below.

Here is the package structure for REST API

Anything which is common to both project and othersystem would go under support folder as shown below

Note: No @Component or @Repository or @Service Annotations on classed in support package

Here is the package structure for Kafka Micro service


Here is the package structure MQ Services


Here is the package structure for Scheduled Jobs


Here is an example microservice

Micro Frontends Architecture


Tech stack At Each layer
| Layer | Technology |
|---|---|
| Client Side MVC | React, Angular, Backbone, Knockout, Vue.js |
| Server Side MVC | Spring MVC, Struts, Servlets, JSP, Apache Wicket, ASP |
| Business | Core Java |
| Data Access / Repository | Jdbc, hibernate, spring-jdbc, spring-orm, jpa |
| Integration | RestTemplate, SOAP Template, Commons http client, HTTP/2 support. OkHttp, google-http, Unirest, Resteasy, restlet, rest-assured |
Also See
- Exposing Spring Boot Rest API
- Spring Boot Bean Validation
- Spring Data JPA Basic Auditing
- Maintaining Data Revisions with Spring Data Envers
- Implementing BFF with NodeJS
- Protecting Spring Rest Services with JWT
- Protecting Spring Rest Services with Spring Security and JWT
- Interservice Communication Using Self-signed JWT
- Spring Batch XML to MySQL DB
- Spring Cloud Task as Kubernetes CronJob
- Mapping Entities and DTOs
- Spring Boot Caching With Ehcache3
- Spring Boot Data JPA Multiple Data Sources
References
- Micro frontends
- BFF Layer
- Growing Object Oriented Software guided by Tests
- Post Vs Put