Source: Dev.to | Dec 27, 2025 (UTC)
User–Order Microservices Application
Business Use Case (Realistic)
A simple e-commerce backend where:
User Service manages users
Order Service creates orders for users
Services communicate via REST
Each service is independently deployable
🧱 Architecture Overview
Components
user-service (Spring Boot)
order-service (Spring Boot)
MySQL (separate DB per service)
Docker
Kubernetes (local or EKS)
Git-based deployment
1️⃣ Project Structure (Mono-Repo for Learning)
microservices-project/
├── user-service/
│ ├── src/main/java/…
│ ├── Dockerfile
│ └── pom.xml
├── order-service/
│ ├── src/main/java/…
│ ├── Dockerfile
│ └── pom.xml
├── k8s/
│ ├── user-deployment.yaml
│ ├── order-deployment.yaml
│ ├── mysql-user.yaml
│ ├── mysql-order.yaml
│ └── ingress.yaml
2️⃣ Develop – User Service
User Entity
@entity
public class User {
@id @GeneratedValue
private Long id;
private String name;
private String email;
}
REST Controller
@RestController
@RequestMapping(“/users”)
public class UserController {
@PostMapping
public User createUser(@RequestBody User user) {
return userRepo.save(user);
}
@GetMapping(“/{id}”)
public User getUser(@PathVariable Long id) {
return userRepo.findById(id).orElseThrow();
}
}
Health Check (mandatory in prod)
@GetMapping(“/health”)
public String health() {
return “UP”;
}
3️⃣ Develop – Order Service (Calls User Service)
Order Entity
C
@entity
public class Order {
@id @GeneratedValue
private Long id;
private Long userId;
private String product;
}
REST Control
@RestController
@RequestMapping(“/orders”)
public class OrderController {
@Autowired
RestTemplate restTemplate;
@PostMapping
public Order createOrder(@RequestBody Order order) {
String userUrl = “http://user-service:8080/users/” + order.getUserId();
restTemplate.getForObject(userUrl, String.class);
return orderRepo.save(order);
}
}
💡 This is real inter-service communication using Kubernetes DNS.
4️⃣ Build – Dockerize Both Services
Dockerfile (same pattern for both
Dockerfile:
FROM openjdk:17-jdk-slim
COPY target/*.jar app.jar
ENTRYPOINT [“java”,”-jar”,”/app.jar”]
Build Images
mvn clean package
docker build -t user-service:1.0 .
docker build -t order-service:1.0 .
5️⃣ Kubernetes – Database Deployment
MySQL for User Service
Yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-user
spec:
replicas: 1
template:
spec:
containers:
– name: mysql
image: mysql:8
env:
– name: MYSQL_DATABASE
value: userdb
– name: MYSQL_ROOT_PASSWORD
value: root
6️⃣ Kubernetes – User Service Deploymen
Yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 2
template:
spec:
containers:
– name: user-service
image: user-service:1.0
ports:
– containerPort: 8080
Service
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 8080
7️⃣ Kubernetes – Order Service Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 2
template:
spec:
containers:
– name: order-service
image: order-service:1.0
8️⃣ Ingress – Single Entry Point
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- http: paths:
- path: /users pathType: Prefix backend: service: name: user-service port: number: 8080
- path: /orders pathType: Prefix backend: service: name: order-service port: number: 8080
9️⃣ Deploy Everything
kubectl apply -f k8s/
Bash
kubectl get pods
kubectl get svc
kubectl get ingress
🔟 Functional Proof (This is Critical)
Create Use
curl -X POST /users -d ‘{“name”:”Raj”,”email”:”[email protected]“}’
Create Order
Copy code
Bash
curl -X POST /orders -d ‘{“userId”:1,”product”:”Laptop”}’
✔ Order service calls user-service ✔ Kubernetes DNS works ✔ DB persists data
1️⃣1️⃣ CI/CD Flow (Real Production Model)
CI
Git push
Build
Test
Docker image build
Push to registry
CD (GitOps)
Update image tag in Git
Auto sync to cluster
1️⃣2️⃣ Rollback Scenario (Very Important)
kubectl rollout undo deployment user-service
OR Git revert (GitOps)
1️⃣3️⃣ Production-Grade Improvements (Next Level)
ConfigMaps & Secrets
HPA (auto scaling)
Circuit breaker
Distributed tracing
Canary deployme
🔁 PART 2 — FULL CI PIPELINE (Jenkins)
Trigger → Build → Test → Docker → Push → Update Git
2.1 Jenkins Prerequisites
Jenkins Server Must Have
Docker installed
Git access
Docker registry credentials
Java 17
kubectl (optional)
2.2 Jenkinsfile (Complete & Real)
Place this Jenkinsfile in repo root.
pipeline {
agent any
environment {
REGISTRY = “docker.io/yourrepo”
IMAGE_TAG = “${BUILD_NUMBER}”
}
stages {
stage('Checkout') { steps { git branch: 'main', url: 'https://github.com/your-org/microservices-project.git' } } stage('Build User Service') { steps { dir('user-service') { sh 'mvn clean package' } } } stage('Build Order Service') { steps { dir('order-service') { sh 'mvn clean package' } } } stage('Docker Build') { steps { sh ''' docker build -t $REGISTRY/user-service:$IMAGE_TAG user-service/ docker build -t $REGISTRY/order-service:$IMAGE_TAG order-service/ ''' } } stage('Docker Push') { steps { withDockerRegistry([credentialsId: 'dockerhub-creds', url: '']) { sh ''' docker push $REGISTRY/user-service:$IMAGE_TAG docker push $REGISTRY/order-service:$IMAGE_TAG ''' } } } stage('Update K8s Manifests Repo') { steps { sh ''' git clone https://github.com/your-org/k8s-manifests.git cd k8s-manifests sed -i "s|image:.*user-service.*|image: $REGISTRY/user-service:$IMAGE_TAG|" user-deployment.yaml sed -i "s|image:.*order-service.*|image: $REGISTRY/order-service:$IMAGE_TAG|" order-deployment.yaml git commit -am "Update images to $IMAGE_TAG" git push ''' } }
Enter fullscreen mode
Exit fullscreen mode


Залишити відповідь