Skip to main content
2026Backend System

Merchants API

Java 21 and Spring Boot 3.5 backend modernization for merchant and transaction workflows.

Merchants API is a production-minded Spring Boot service with resource-oriented REST paths, immutable DTO records, Flyway migrations, Oracle runtime support, H2 tests, externalized configuration, and RFC 7807-style error responses.

Java 21Spring Boot 3.5Spring Data JPAOracleH2FlywayMaven
Merchants API bannerAPI service previewBackend application preview

Evidence

Case Study Highlights

Java 21

modern runtime

Spring 3.5

framework baseline

Flyway

controlled schemas

RFC 7807

problem responses

Context

Problem and ownership

The original project could read as a basic CRUD API. The modernization reframed it around backend reliability: explicit resource paths, schema control, test-friendly profiles, immutable contracts, and predictable failure responses.

My role

Modernized the API structure, runtime configuration, database migration approach, DTO boundaries, and error handling.

Constraints

What shaped the solution

  • The architecture follows the KISS principle so the codebase stays clean, reviewable, and efficient.
  • Oracle support needed to remain available for production-style runtime configuration.
  • Tests needed to run without requiring a local Oracle instance.
  • JPA should validate schemas created by migrations instead of silently generating tables.

Architecture

System design and request flow

The service exposes merchant and transaction resources through Spring Web controllers, maps requests into immutable DTO records, persists entities through Spring Data JPA, and relies on profile-specific Flyway migrations for schema setup.

Request and Data Flow

  1. 1REST request
  2. 2Controller validation boundary
  3. 3Service and repository layer
  4. 4JPA persistence
  5. 5Flyway-managed schema
  6. 6Oracle runtime or H2 test database

Core Components

  • Merchant endpoints create and retrieve merchant resources.
  • Transaction endpoints create and list payment transaction records.
  • Flyway migration folders separate Oracle and H2 schema concerns.
  • Global exception handling returns predictable problem responses.

Technical decisions

Key choices and why they mattered

Moved toward Java 21 and Spring Boot 3.5

The modern runtime supports current Spring conventions, records, improved language ergonomics, and a cleaner portfolio signal.

Used H2 in Oracle compatibility mode for tests

Tests can run quickly without an Oracle install while keeping SQL close to the production-style database profile.

Used RFC 7807-style error responses

Standard problem responses make API failures easier for clients and reviewers to understand.

Trade-offs

What the design optimizes for and gives up

  • H2 compatibility is useful for test speed, but it is not a perfect substitute for Oracle integration testing.
  • Keeping the service intentionally small improves reviewability, but it limits demonstration of broader distributed patterns.
  • Flyway adds setup discipline, but it requires careful migration hygiene as the domain grows.

Production readiness

Reliability, security, and delivery evidence

  • Runtime database settings are externalized through environment variables.
  • Flyway owns schema creation and Hibernate validates instead of auto-generating tables.
  • The test profile uses H2 so CI can execute without Oracle.
  • Global exception handling gives clients consistent error responses.

Results

What changed because of the work

  • Transformed the project from a tutorial-like CRUD service into a clearer backend modernization story.
  • Added migration-controlled schemas and test-friendly database profiles.
  • Improved API contract clarity through immutable DTOs and resource-oriented paths.

Next improvements

Where I would take it next

  • Add containerized Oracle XE integration tests for higher fidelity.
  • Add OpenAPI documentation and request examples for reviewers.
  • Add authentication and authorization boundaries if the service grows beyond portfolio scope.