Skip to content

ashim-roy/ProductServiceSpring

Repository files navigation

ProductServiceSpring

A Spring Boot REST API for managing a product catalog, built with a dual-datasource strategy — a live MySQL database and an external FakeStore API proxy.

The project also includes a hands-on demonstration of all four JPA inheritance mapping strategies.


Tech Stack

Layer Technology
Language Java 17
Framework Spring Boot 3.2.3
Persistence Spring Data JPA + Hibernate
Database MySQL 8
External API FakeStore API via RestTemplate
Boilerplate Reduction Lombok
Build Tool Maven

Architecture Overview

The service exposes a single REST controller (ProductController) backed by a swappable service layer via Spring's @Qualifier annotation.

Client Request
     │
     ▼
ProductController  (/products)
     │
     ├─── @Qualifier("SelfProductService")
     │         └── ProductServiceImpl  ──► ProductRepo (MySQL JPA)
     │                                 └── CategoryRepo (MySQL JPA)
     │
     └─── @Qualifier("FakeProductService")
               └── FakeStoreProductServiceImpl ──► FakeStoreClient (RestTemplate)
                                                        └── fakestoreapi.com

Switch between the two implementations by changing the @Qualifier in ProductController.

No other code needs to change — this is the Strategy Pattern in action.


REST API Endpoints

Base path: /products

Method Endpoint Description
GET /products/{id} Get a product by ID
GET /products Get all products
POST /products Create a new product
PUT /products/{id} Update an existing product
DELETE /products/{id} Delete a product by ID

Sample Request — Create Product

POST /products

{
  "title": "Wireless Headphones",
  "description": "Over-ear noise cancelling",
  "price": 2999,
  "category": {
    "name": "Electronics"
  }
}

Sample Error Response

HTTP 404

{
  "message": "Product not found with id: 42",
  "status": "failure"
}

Project Structure

src/main/java/com/example/productservicecp/
│
├── ProductServiceJanBatchApplication.java
│
├── controllers/
│   ├── ProductController.java
│   └── advices/
│       └── ProductControllerAdvice.java
│
├── services/
│   ├── ProductService.java
│   ├── ProductServiceImpl.java
│   ├── FakeStoreProductServiceImpl.java
│   └── FakeproductServiceObjectMapper.java
│
├── thirdpartyclients/
│   └── FakeStoreClient.java
│
├── models/
│   ├── BaseModel.java
│   ├── Product.java
│   └── Category.java
│
├── repository/
│   ├── ProductRepo.java
│   └── CategoryRepo.java
│
├── dtos/
│   ├── FakeStoreProductDto.java
│   └── ExceptionDto.java
│
├── exceptions/
│   └── ProductNotFoundException.java
│
└── inheritancedemo/
    ├── singletable/
    ├── tableperclass/
    ├── joinedtable/
    └── mappedsuper/

Data Model

Product

Field Type Notes
id Long Auto-generated primary key
title String Product name
description String Product description
price Long Price in smallest currency unit
category Category @ManyToOne relationship

Category

Field Type Notes
id Long Auto-generated
name String Category name

Key Behaviour

When adding or updating a product, the service checks whether the category already exists by name using:

CategoryRepo.findByName()

If it exists, the existing category is reused. Otherwise, a new category is created.

This prevents duplicate category rows.


Key Design Patterns

Strategy Pattern

ProductService interface with two implementations:

  • ProductServiceImpl
  • FakeStoreProductServiceImpl

The controller depends on the interface, not the concrete class.

Implementation is swapped via @Qualifier.


DTO Pattern

FakeStoreProductDto decouples the internal Product domain model from the external API contract.

Conversion happens inside FakeStoreProductServiceImpl.


Global Exception Handling

ProductControllerAdvice uses @RestControllerAdvice scoped to ProductController.

It catches ProductNotFoundException and returns structured JSON error responses.


Third-Party Client Abstraction

FakeStoreClient encapsulates all RestTemplate logic for external API interaction.

The service layer never directly interacts with RestTemplate.


JPA Inheritance Demo

The inheritancedemo package demonstrates all four Hibernate inheritance strategies using a User → Mentor / Student hierarchy.

Strategy Tables Created Trade-off
SINGLE_TABLE One table with discriminator column Fast reads, nullable columns
TABLE_PER_CLASS One table per concrete class No joins, duplicated schema
JOINED Parent + child tables Normalized, slower joins
MAPPED_SUPERCLASS Only child tables No polymorphic parent queries

Setup & Running Locally

Prerequisites

  • Java 17+
  • Maven 3.8+
  • MySQL 8

1. Configure Database

CREATE DATABASE jan24productservice;

CREATE USER 'jan24productservice'@'localhost'
IDENTIFIED BY 'your_password';

GRANT ALL PRIVILEGES
ON jan24productservice.*
TO 'jan24productservice'@'localhost';

Update:

src/main/resources/application.properties
spring.datasource.password=your_password

2. Build & Run

./mvnw spring-boot:run

Application starts on:

http://localhost:8080

3. Switch Between Datasources

In ProductController.java:

// Use local MySQL
@Qualifier("SelfProductService")

// Use FakeStore API
@Qualifier("FakeProductService")

Configuration Reference

# FakeStore API
fakestore.api.url=https://fakestoreapi.com/products/{id}

# Database
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/jan24productservice
spring.datasource.username=jan24productservice
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Hibernate
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

What Is Not Implemented

  • Elasticsearch
  • Kafka
  • Spring Cloud / Microservices
  • Authentication / Authorization
  • Pagination on GET /products
  • Full implementation of getAllProducts()
  • Full implementation of deleteProductById()

License

MIT

About

A Spring Boot REST API for managing a product catalog, built with a dual-datasource strategy — a live MySQL database and an external FakeStore API proxy. The project also includes a hands-on demonstration of all four JPA inheritance mapping strategies.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages