A demonstration of microservices architecture using Spring Boot and Spring Cloud Netflix stack, implementing a movie catalog system with service discovery and inter-service communication.
- Architecture Overview
- Services
- Service Interactions
- API Documentation
- Technology Stack
- Getting Started
- Service Configuration
This project demonstrates a microservices architecture with the following components:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Discovery Server โ
โ (Netflix Eureka Server) โ
โ Port: 8761 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Service Registration
โโโโโโโโโโโโโโผโโโโโโโโโโโโโ
โ โ โ
โโโโโโโโโผโโโโโโโ โโโโผโโโโโโโโโโโ โโผโโโโโโโโโโโโโโโโ
โ Movie โ โ Movie โ โ Ratings โ
โ Catalog โ โ Info โ โ Data โ
โ Service โ โ Service โ โ Service โ
โ Port: 8081 โ โ Port: 8082 โ โ Port: 8083 โ
โโโโโโโโฌโโโโโโโโ โโโโโโโโฒโโโโโโโ โโโโโโฒโโโโโโโโโโโโ
โ โ โ
โ REST API โ โ
โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโ
(via Service Discovery)
- Service Discovery: Netflix Eureka for dynamic service registration and discovery
- Client-Side Load Balancing: Using Spring Cloud LoadBalancer with RestTemplate
- Inter-Service Communication: RESTful APIs with service-to-service calls
- Aggregation Pattern: Movie Catalog Service aggregates data from multiple services
Purpose: Service registry that enables service discovery using Netflix Eureka.
Port: 8761
Responsibilities:
- Maintains a registry of all microservice instances
- Provides service location information to clients
- Enables dynamic scaling and load balancing
- Health checking of registered services
Technology:
- Spring Cloud Netflix Eureka Server
@EnableEurekaServerannotation
Configuration Highlights:
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=falseAccess:
- Eureka Dashboard:
http://localhost:8761
Purpose: Aggregator service that provides personalized movie catalogs for users by combining data from Movie Info and Ratings services.
Port: 8081
Application Name: movie-catalog-service
Responsibilities:
- Acts as an API Gateway/Aggregator for client applications
- Fetches user ratings from Ratings Data Service
- Fetches movie details from Movie Info Service
- Combines data to create personalized movie catalogs
- Implements client-side load balancing
Key Components:
- RestTemplate: Configured with
@LoadBalancedfor service discovery and load balancing - WebClient: Reactive HTTP client (configured but not currently used in the implementation)
Dependencies:
- Movie Info Service (for movie details)
- Ratings Data Service (for user ratings)
- Discovery Server (for service discovery)
Purpose: Provides detailed information about movies.
Port: 8082
Application Name: movie-info-service
Responsibilities:
- Stores and serves movie metadata (title, description)
- Returns movie information by movie ID
- Currently uses in-memory data store (hardcoded HashMap)
Data Store (Sample Data):
Movie ID: 100 - Transformers (SciFi movie)
Movie ID: 101 - Titanic (Romantic movie)
Movie ID: 102 - Silent Place (Horror movie)
Purpose: Manages movie ratings provided by users.
Port: 8083
Application Name: ratings-data-service
Responsibilities:
- Stores and serves user ratings for movies
- Provides ratings by movie ID
- Provides all ratings for a specific user
- Currently uses in-memory data store (hardcoded HashMap)
Data Store (Sample Data):
User 1000:
- Movie 100: Rating 5
- Movie 101: Rating 5
User 1001:
- Movie 100: Rating 5
- Movie 101: Rating 4
- Movie 102: Rating 3
Client
โ
โ GET /catalog/{userId}
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Movie Catalog Service โ
โ (Port: 8081) โ
โโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโ
โ โ
โ โ Step 1: Get user ratings
โ โ GET /ratings/user/{userId}
โ โผ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ Ratings Data Service โ
โ โ (Port: 8083) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ โ Returns: UserRating object
โ โ { userId, List<Rating> }
โ โ
โโโโโโโโโโโโโโโ
โ
โ Step 2: For each rating, get movie details
โ GET /movies/{movieId}
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Movie Info Service โ
โ (Port: 8082) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Returns: Movie object
โ { movieId, name, description }
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Movie Catalog Service โ
โ (Aggregates data) โ
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ
โ Returns: List<CatalogItem>
โ { name, description, rating }
โผ
Client
- Startup: Each service registers itself with the Discovery Server (Eureka)
- Service Lookup: Movie Catalog Service queries Eureka for service locations
- Load Balancing: RestTemplate with
@LoadBalancedautomatically distributes requests - Resilience: Eureka maintains heartbeats and updates service registry dynamically
- Protocol: HTTP/REST
- Service Resolution: Logical service names (e.g.,
http://movie-info-service) are resolved to actual host:port by Eureka client - Load Balancing: Client-side load balancing using Spring Cloud LoadBalancer
- HTTP Client: RestTemplate with Apache HttpComponents (3-second connection timeout)
Endpoint: GET /catalog/{userId}
Description: Retrieves a personalized movie catalog for a specific user, including movie details and their ratings.
Path Parameters:
userId(String): Unique identifier of the user
Response: 200 OK
[
{
"name": "Transformers",
"description": "Transformers is a SciFi movie",
"rating": 5
},
{
"name": "Titanic",
"description": "Titanic is a romantic movie",
"rating": 5
}
]Response Model: CatalogItem[]
name(String): Movie titledescription(String): Movie descriptionrating(int): User's rating for the movie
Example:
curl http://localhost:8081/catalog/1000Internal Flow:
- Calls Ratings Data Service to get user's ratings
- For each rated movie, calls Movie Info Service to get movie details
- Aggregates the data into CatalogItem objects
Endpoint: GET /movies/{movieId}
Description: Retrieves detailed information about a specific movie.
Path Parameters:
movieId(String): Unique identifier of the movie
Response: 200 OK
{
"movieId": "100",
"name": "Transformers",
"description": "Transformers is a SciFi movie"
}Response Model: Movie
movieId(String): Unique movie identifiername(String): Movie titledescription(String): Movie description
Example:
curl http://localhost:8082/movies/100Available Movies:
100: Transformers101: Titanic102: Silent Place
Endpoint: GET /ratings/{movieId}
Description: Retrieves rating information for a specific movie.
Path Parameters:
movieId(String): Unique identifier of the movie
Response: 200 OK
{
"movieId": "100",
"userId": "1000",
"rating": 5
}Response Model: Rating
movieId(String): Unique movie identifieruserId(String): User who provided the ratingrating(int): Rating value
Example:
curl http://localhost:8083/ratings/100Endpoint: GET /ratings/user/{userId}
Description: Retrieves all movie ratings provided by a specific user.
Path Parameters:
userId(String): Unique identifier of the user
Response: 200 OK
{
"userId": "1000",
"ratings": [
{
"movieId": "100",
"userId": "1000",
"rating": 5
},
{
"movieId": "101",
"userId": "1000",
"rating": 5
}
]
}Response Model: UserRating
userId(String): Unique user identifierratings(Rating[]): List of all ratings by the usermovieId(String): Movie identifieruserId(String): User identifierrating(int): Rating value
Example:
curl http://localhost:8083/ratings/user/1000Available Users:
1000: Has rated movies 100 and 1011001: Has rated movies 100, 101, and 102
- Java: Version 20
- Spring Boot: 3.0.5
- Spring Cloud: 2022.0.2
- Maven: Build and dependency management
- Netflix Eureka: Service discovery and registration
- Spring Cloud Netflix Eureka Client: Service discovery client
- Spring Cloud LoadBalancer: Client-side load balancing
- RestTemplate: Synchronous HTTP client with load balancing
- WebClient: Reactive HTTP client (Spring WebFlux)
- Apache HttpComponents: HTTP client implementation
- Lombok: Reduces boilerplate code with annotations
- Log4j2: Logging framework
- Java 20 or higher
- Maven 3.6+
- IDE (IntelliJ IDEA, Eclipse, or VS Code)
Important: Services must be started in the following order to ensure proper registration and communication.
cd discovery-server
./mvnw spring-boot:runWait for the server to start completely. Access Eureka Dashboard at: http://localhost:8761
cd movie-info-service
./mvnw spring-boot:runVerify registration in Eureka Dashboard.
cd ratings-data-service
./mvnw spring-boot:runVerify registration in Eureka Dashboard.
cd movie-catalog-service
./mvnw spring-boot:runVerify registration in Eureka Dashboard.
# From each service directory
./mvnw clean installOnce all services are running, test the movie catalog endpoint:
# Get catalog for user 1000
curl http://localhost:8081/catalog/1000
# Get catalog for user 1001
curl http://localhost:8081/catalog/1001Expected Response for user 1000:
[
{
"name": "Transformers",
"description": "Transformers is a SciFi movie",
"rating": 5
},
{
"name": "Titanic",
"description": "Titanic is a romantic movie",
"rating": 5
}
]File: discovery-server/src/main/resources/application.properties
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false- Runs on port 8761
- Does not register itself with Eureka
- Does not fetch registry from other Eureka servers
File: movie-catalog-service/src/main/resources/application.properties
spring.application.name=movie-catalog-service
server.port=8081- Service name used for discovery:
movie-catalog-service - REST API port: 8081
- Automatically registers with Eureka
Key Configurations:
- RestTemplate with
@LoadBalancedfor service discovery - Connection timeout: 3000ms (3 seconds)
- WebClient builder for reactive calls (future use)
File: movie-info-service/src/main/resources/application.properties
spring.application.name=movie-info-service
server.port=8082- Service name used for discovery:
movie-info-service - REST API port: 8082
- Automatically registers with Eureka
File: ratings-data-service/src/main/resources/application.properties
spring.application.name=ratings-data-service
server.port=8083- Service name used for discovery:
ratings-data-service - REST API port: 8083
- Automatically registers with Eureka
Represents a movie in a user's personalized catalog.
{
"name": String, // Movie title
"description": String, // Movie description
"rating": int // User's rating
}Represents movie information.
{
"movieId": String, // Unique identifier
"name": String, // Movie title
"description": String // Movie description
}Represents a single movie rating by a user.
{
"movieId": String, // Movie identifier
"userId": String, // User identifier
"rating": int // Rating value (1-5)
}Represents all ratings provided by a user.
{
"userId": String, // User identifier
"ratings": Rating[] // List of ratings
}- Automatic Registration: All services register with Eureka on startup
- Health Monitoring: Eureka tracks service health via heartbeats
- Dynamic Scaling: New instances are automatically discovered
- Fault Tolerance: Failed instances are removed from registry
- Client-Side: RestTemplate with
@LoadBalancedannotation - Algorithm: Default Round-robin (configurable)
- No Single Point of Failure: Load balancing logic distributed to clients
- Service Names: Logical names resolve to actual endpoints
- RESTful APIs: Standard HTTP/JSON communication
- Timeouts: Configured connection timeouts prevent hanging requests
- Loose Coupling: Services only know service names, not locations
- Circuit Breaker: Add Resilience4j for fault tolerance
- API Gateway: Implement Spring Cloud Gateway for unified entry point
- Configuration Server: Centralized configuration management
- Distributed Tracing: Add Sleuth and Zipkin for request tracing
- Database Integration: Replace in-memory data with persistent storage
- Security: Implement OAuth2/JWT authentication
- Caching: Add Redis for caching frequently accessed data
- Message Queue: Implement async communication with RabbitMQ/Kafka
- Monitoring: Add Spring Boot Actuator and Prometheus/Grafana
- Containerization: Docker and Kubernetes deployment
- All services currently use in-memory data stores for demonstration purposes
- The Movie Catalog Service demonstrates the aggregator pattern
- Load balancing is enabled but requires multiple instances to see its effect
- All inter-service calls use service names, not hardcoded URLs
- Connection timeout is set to 3 seconds to prevent long waits
This project is for educational and demonstration purposes.
Package: io.emkae
For more information or questions about this microservices implementation, please refer to the individual service source code.