Building BBank Architecture with Spring Cloud, Gateway & Eureka
Note: This tutorial implements the architecture shown in
We'll create 5 microservices: Eureka Server, API Gateway, Account Service, Customer Service, and Transaction Service.

📁 Project Structure
eureka-server
- Service registryapi-gateway
- Entry point for all requestsaccount-service
- Manages bank accountscustomer-service
- Manages customer informationtransaction-service
- Handles money transfers between accounts
Step 1: Create Eureka Server
The Eureka Server acts as a service registry where all microservices register themselves.
📁 File: eureka-server/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bbank</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
📁 File: eureka-server/src/main/resources/application.yml
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
server:
enable-self-preservation: false
📁 File: eureka-server/src/main/java/com/bbank/eurekaserver/EurekaServerApplication.java
package com.bbank.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Step 2: Create API Gateway
The API Gateway routes requests to appropriate microservices and provides a single entry point.
📁 File: api-gateway/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bbank</groupId>
<artifactId>api-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api-gateway</name>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
📁 File: api-gateway/src/main/resources/application.yml
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: account-service
uri: lb://account-service
predicates:
- Path=/api/accounts/**
- id: customer-service
uri: lb://customer-service
predicates:
- Path=/api/customers/**
- id: transaction-service
uri: lb://transaction-service
predicates:
- Path=/api/transactions/**
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
fetch-registry: true
register-with-eureka: true
📁 File: api-gateway/src/main/java/com/bbank/apigateway/ApiGatewayApplication.java
package com.bbank.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
Step 3: Create Account Service
This service manages bank accounts and their balances.
📁 File: account-service/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bbank</groupId>
<artifactId>account-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>account-service</name>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
📁 File: account-service/src/main/resources/application.yml
server:
port: 8081
spring:
application:
name: account-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
📁 File: account-service/src/main/java/com/bbank/accountservice/model/Account.java
package com.bbank.accountservice.model;
public class Account {
private Long id;
private Long customerId;
private String accountNumber;
private Double balance;
// Constructors
public Account() {}
public Account(Long id, Long customerId, String accountNumber, Double balance) {
this.id = id;
this.customerId = customerId;
this.accountNumber = accountNumber;
this.balance = balance;
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getCustomerId() { return customerId; }
public void setCustomerId(Long customerId) { this.customerId = customerId; }
public String getAccountNumber() { return accountNumber; }
public void setAccountNumber(String accountNumber) { this.accountNumber = accountNumber; }
public Double getBalance() { return balance; }
public void setBalance(Double balance) { this.balance = balance; }
}
📁 File: account-service/src/main/java/com/bbank/accountservice/repository/AccountRepository.java
package com.bbank.accountservice.repository;
import com.bbank.accountservice.model.Account;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Repository
public class AccountRepository {
private final ConcurrentHashMap<Long, Account> accounts = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public Account save(Account account) {
if (account.getId() == null) {
account.setId(idGenerator.getAndIncrement());
}
accounts.put(account.getId(), account);
return account;
}
public Account findById(Long id) {
return accounts.get(id);
}
public List<Account> findByCustomerId(Long customerId) {
return accounts.values().stream()
.filter(acc -> acc.getCustomerId().equals(customerId))
.toList();
}
public List<Account> findAll() {
return new ArrayList<>(accounts.values());
}
public boolean updateBalance(Long id, Double newBalance) {
Account account = accounts.get(id);
if (account != null) {
account.setBalance(newBalance);
return true;
}
return false;
}
}
📁 File: account-service/src/main/java/com/bbank/accountservice/controller/AccountController.java
package com.bbank.accountservice.controller;
import com.bbank.accountservice.model.Account;
import com.bbank.accountservice.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/accounts")
public class AccountController {
@Autowired
private AccountRepository accountRepository;
@GetMapping
public List<Account> getAllAccounts() {
return accountRepository.findAll();
}
@GetMapping("/{id}")
public Account getAccountById(@PathVariable Long id) {
return accountRepository.findById(id);
}
@GetMapping("/customer/{customerId}")
public List<Account> getAccountsByCustomerId(@PathVariable Long customerId) {
return accountRepository.findByCustomerId(customerId);
}
@PostMapping
public Account createAccount(@RequestBody Account account) {
return accountRepository.save(account);
}
@PutMapping("/{id}/balance")
public boolean updateBalance(@PathVariable Long id, @RequestBody Double newBalance) {
return accountRepository.updateBalance(id, newBalance);
}
}
📁 File: account-service/src/main/java/com/bbank/accountservice/AccountServiceApplication.java
package com.bbank.accountservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class AccountServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AccountServiceApplication.class, args);
}
}
Step 4: Create Customer Service
This service manages customer information.
📁 File: customer-service/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bbank</groupId>
<artifactId>customer-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customer-service</name>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
📁 File: customer-service/src/main/resources/application.yml
server:
port: 8082
spring:
application:
name: customer-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
📁 File: customer-service/src/main/java/com/bbank/customerservice/model/Customer.java
package com.bbank.customerservice.model;
public class Customer {
private Long id;
private String name;
private String email;
private String phone;
public Customer() {}
public Customer(Long id, String name, String email, String phone) {
this.id = id;
this.name = name;
this.email = email;
this.phone = phone;
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
}
📁 File: customer-service/src/main/java/com/bbank/customerservice/repository/CustomerRepository.java
package com.bbank.customerservice.repository;
import com.bbank.customerservice.model.Customer;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Repository
public class CustomerRepository {
private final ConcurrentHashMap<Long, Customer> customers = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public Customer save(Customer customer) {
if (customer.getId() == null) {
customer.setId(idGenerator.getAndIncrement());
}
customers.put(customer.getId(), customer);
return customer;
}
public Customer findById(Long id) {
return customers.get(id);
}
public List<Customer> findAll() {
return new ArrayList<>(customers.values());
}
}
📁 File: customer-service/src/main/java/com/bbank/customerservice/controller/CustomerController.java
package com.bbank.customerservice.controller;
import com.bbank.customerservice.model.Customer;
import com.bbank.customerservice.repository.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/customers")
public class CustomerController {
@Autowired
private CustomerRepository customerRepository;
@GetMapping
public List<Customer> getAllCustomers() {
return customerRepository.findAll();
}
@GetMapping("/{id}")
public Customer getCustomerById(@PathVariable Long id) {
return customerRepository.findById(id);
}
@PostMapping
public Customer createCustomer(@RequestBody Customer customer) {
return customerRepository.save(customer);
}
}
📁 File: customer-service/src/main/java/com/bbank/customerservice/CustomerServiceApplication.java
package com.bbank.customerservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class CustomerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
}
Step 5: Create Transaction Service
This service handles money transfers between accounts using Feign clients to communicate with Account Service.
📁 File: transaction-service/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bbank</groupId>
<artifactId>transaction-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>transaction-service</name>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
📁 File: transaction-service/src/main/resources/application.yml
server:
port: 8083
spring:
application:
name: transaction-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/model/Transaction.java
package com.bbank.transactionservice.model;
public class Transaction {
private Long id;
private Long fromAccountId;
private Long toAccountId;
private Double amount;
private String status; // e.g., "SUCCESS", "FAILED"
public Transaction() {}
public Transaction(Long id, Long fromAccountId, Long toAccountId, Double amount, String status) {
this.id = id;
this.fromAccountId = fromAccountId;
this.toAccountId = toAccountId;
this.amount = amount;
this.status = status;
}
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getFromAccountId() { return fromAccountId; }
public void setFromAccountId(Long fromAccountId) { this.fromAccountId = fromAccountId; }
public Long getToAccountId() { return toAccountId; }
public void setToAccountId(Long toAccountId) { this.toAccountId = toAccountId; }
public Double getAmount() { return amount; }
public void setAmount(Double amount) { this.amount = amount; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/client/AccountServiceClient.java
package com.bbank.transactionservice.client;
import com.bbank.transactionservice.model.Account;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(name = "account-service")
public interface AccountServiceClient {
@GetMapping("/api/accounts/{id}")
Account getAccount(@PathVariable("id") Long id);
@PutMapping("/api/accounts/{id}/balance")
Boolean updateBalance(@PathVariable("id") Long id, @RequestBody Double newBalance);
}
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/repository/TransactionRepository.java
package com.bbank.transactionservice.repository;
import com.bbank.transactionservice.model.Transaction;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Repository
public class TransactionRepository {
private final ConcurrentHashMap<Long, Transaction> transactions = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public Transaction save(Transaction transaction) {
if (transaction.getId() == null) {
transaction.setId(idGenerator.getAndIncrement());
}
transactions.put(transaction.getId(), transaction);
return transaction;
}
public List<Transaction> findAll() {
return new ArrayList<>(transactions.values());
}
public List<Transaction> findByAccountId(Long accountId) {
return transactions.values().stream()
.filter(t -> t.getFromAccountId().equals(accountId) || t.getToAccountId().equals(accountId))
.toList();
}
}
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/service/TransactionService.java
package com.bbank.transactionservice.service;
import com.bbank.transactionservice.client.AccountServiceClient;
import com.bbank.transactionservice.model.Account;
import com.bbank.transactionservice.model.Transaction;
import com.bbank.transactionservice.repository.TransactionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TransactionService {
@Autowired
private AccountServiceClient accountServiceClient;
@Autowired
private TransactionRepository transactionRepository;
public Transaction transferMoney(Long fromAccountId, Long toAccountId, Double amount) {
Account fromAccount = accountServiceClient.getAccount(fromAccountId);
Account toAccount = accountServiceClient.getAccount(toAccountId);
if (fromAccount == null || toAccount == null) {
return new Transaction(null, fromAccountId, toAccountId, amount, "FAILED - Account not found");
}
if (fromAccount.getBalance() < amount) {
return new Transaction(null, fromAccountId, toAccountId, amount, "FAILED - Insufficient balance");
}
// Deduct from sender
boolean fromUpdated = accountServiceClient.updateBalance(fromAccountId, fromAccount.getBalance() - amount);
if (!fromUpdated) {
return new Transaction(null, fromAccountId, toAccountId, amount, "FAILED - Could not update sender balance");
}
// Add to receiver
boolean toUpdated = accountServiceClient.updateBalance(toAccountId, toAccount.getBalance() + amount);
if (!toUpdated) {
// Rollback sender
accountServiceClient.updateBalance(fromAccountId, fromAccount.getBalance());
return new Transaction(null, fromAccountId, toAccountId, amount, "FAILED - Could not update receiver balance");
}
Transaction transaction = new Transaction();
transaction.setFromAccountId(fromAccountId);
transaction.setToAccountId(toAccountId);
transaction.setAmount(amount);
transaction.setStatus("SUCCESS");
return transactionRepository.save(transaction);
}
public Iterable<Transaction> getAllTransactions() {
return transactionRepository.findAll();
}
public Iterable<Transaction> getTransactionsByAccountId(Long accountId) {
return transactionRepository.findByAccountId(accountId);
}
}
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/controller/TransactionController.java
package com.bbank.transactionservice.controller;
import com.bbank.transactionservice.model.Transaction;
import com.bbank.transactionservice.service.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/transactions")
public class TransactionController {
@Autowired
private TransactionService transactionService;
@PostMapping("/transfer")
public Transaction transferMoney(@RequestParam Long fromAccountId,
@RequestParam Long toAccountId,
@RequestParam Double amount) {
return transactionService.transferMoney(fromAccountId, toAccountId, amount);
}
@GetMapping
public Iterable<Transaction> getAllTransactions() {
return transactionService.getAllTransactions();
}
@GetMapping("/account/{accountId}")
public Iterable<Transaction> getTransactionsByAccountId(@PathVariable Long accountId) {
return transactionService.getTransactionsByAccountId(accountId);
}
}
📁 File: transaction-service/src/main/java/com/bbank/transactionservice/TransactionServiceApplication.java
package com.bbank.transactionservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class TransactionServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TransactionServiceApplication.class, args);
}
}
✅ Final Step: Run All Services
Start services in this order:
- Eureka Server → http://localhost:8761
- Account Service
- Customer Service
- Transaction Service
- API Gateway → http://localhost:8080
🧪 Test Endpoints via Gateway
- Get all accounts:
GET http://localhost:8080/api/accounts
- Create customer:
POST http://localhost:8080/api/customers
- Transfer money:
POST http://localhost:8080/api/transactions/transfer?fromAccountId=1&toAccountId=2&amount=100
🎉 Congratulations! You now have a fully working Spring Cloud Microservices system with:
- Service Discovery (Eureka)
- API Gateway (Spring Cloud Gateway)
- Inter-service communication (Feign Client)
- REST APIs for Account, Customer, Transaction