Getting Started | Building an Application with Spring Boot
Build an application bank with Spring boot and Angular use Jpa
Objective:
In this tutorials we will build an application bank to create Standing Account and Savings Account the user can do operations deposit, debit or transfer from account to another the admin can add the accounts with balance, tax or loan for any account.
Used Skills in this project:
Java, SpringBoot, MicroServices, REST WebServices, JPA, Hibernate, MySQL Database, Maven, Angular, GitHub, SpringBoot Embedded Tomcat Server, STS-Eclipse IDE
Tools to be used
° Use any IDE to develop the Spring and Hibernate project. It may be STS/Eclipse/Netbeans. Here, we are using STS (Spring Tool Suite).
° Mysql for the database.
° Use any IDE to develop the Angular project. It may be Visual Studio Code/Sublime. Here, we are using Visual Studio Code.
° Server: Apache Tomcat/JBoss/Glassfish/Weblogic/Websphere.
Spring MVC
Spring MVC is the primary web framework built on the Servlet API. It is build on the popular MVC design pattern. MVC (Model-View-Controller) is a software architecture pattern, which separates application into three areas: model, view, and controller. The model represents a Java object carrying data. The view represents the visualization of the data that the model contains. The controller controls the data flow into model object and updates the view when the data changes. It separates the view and model.
Spring Boot Architecture
Spring Boot is a module of the Spring Framework. It is used to create stand-alone, production-grade Spring Based Applications with minimum efforts. It is developed on top of the core Spring Framework.
Introduction mysql to database
MySQL is a database management system that allows you to manage relational databases. It is open source software backed by Oracle. It means you can use MySQL without paying a dime. Also, if you want, you can change its source code to suit your needs. MySQL can run on various platforms UNIX, Linux, Windows, etc. You can install it on a server or even in a desktop. Besides, MySQL is reliable, scalable, and fast.
Introduction to the POM
POM A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target; the source directory, which is src/main/java; the test source directory, which is src/main/java; and so on. When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.
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>2.4.1</version>
<relativePath/>
</parent>
<groupId>org.bank</groupId>
<artifactId>bank</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bank</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Properties File
Properties files are used to keep ‘N’ number of properties in a single file to run the application in a different environment. In Spring Boot, properties are kept in the application.properties file under the classpath.
The application.properties file is located in the src/main/resources directory. The code for sample application.properties
We need to create database name it bank
src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/bank?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.activemq.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
server.port=8080
spring.jpa.database=MYSQL
Class Diagram
Modals / Entities
An entity is a lightweight persistence domain object. Typically, an entity represents a table in a relational database, and each entity instance corresponds to a row in that table. The primary programming artifact of an entity is the entity class, although entities can use helper classes.
We need to create these entities
-> Account
-> Client
-> Credit
-> Operation
-> SavingsAccount
-> StandingAccount
-> OrderProductPk
-> Withdraw
Here, we are creating an Entity
Account.java This object content id, code, createDate, balance and relational @ManyToOne with Client and @OneToMany with Operation
src/main/java/com/bank/model/Account.java):
package com.bank.modal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
@Table(name = "accounts")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Account implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String code;
private Date createDate;
private double balance;
@ManyToOne
@JsonBackReference(value = "client")
private Client client;
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
private List<Operation> operations;
public Account() {
super();
}
public Account(String code, Date createDate, double balance, Client client, List<Operation> operations) {
super();
this.code = code;
this.createDate = createDate;
this.balance = balance;
this.client = client;
this.operations = operations;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public List<Operation> getOperations() {
return operations;
}
public void setOperations(List<Operation> operations) {
this.operations = operations;
}
public void doOperation(Operation operation) {
if (getOperations() == null) {
this.operations = new ArrayList<>();
}
getOperations().add(operation);
operation.setAccount(this);
}
}
Here, we are creating an Entity
Client.java This object content id, name, username, password, email, admin and relational @OneToMany with Account
src/main/java/com/bank/model/Client.java):
package com.bank.modal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
@Entity
@Table(name = "clients")
public class Client implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "_username", unique = true)
private String username;
@Column(name = "_password")
private String password;;
@Column(name = "_name")
private String name;;
@Column(name = "_email")
private String email;
private boolean admin;
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)
private List<Account> accounts;
public Client() {
super();
}
public Client(String username, String password, String name, String email, boolean admin, List<Account> accounts) {
super();
this.username = username;
this.password = password;
this.name = name;
this.email = email;
this.admin = admin;
this.accounts = accounts;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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 boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public void addAccount(Account account) {
if (getAccounts() == null) {
this.accounts = new ArrayList<>();
}
getAccounts().add(account);
account.setClient(this);
}
}
Here, we are creating an Entity
Credit.java This object extends Operation
src/main/java/com/bank/model/Credit.java):
package com.bank.modal;
import java.util.Date;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("C")
public class Credit extends Operation {
/**
*
*/
private static final long serialVersionUID = 1L;
public Credit() {
super();
}
public Credit(Date operationDate, double amount, String typeOperation, Account account) {
super(operationDate, amount, typeOperation, account);
}
}
Here, we are creating an Entity
Operation.java This object content numberOperation, operationDate, amount, typeOperation and relational @ManyToOne with Account
src/main/java/com/bank/model/Operation.java):
package com.bank.modal;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
@Table(name = "accounts")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Operation implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long numberOperation;
private Date operationDate;
private double amount;
private String typeOperation;
@ManyToOne
@JsonBackReference(value = "accounnt")
private Account account;
public Operation() {
super();
}
public Operation(Date operationDate, double amount, String typeOperation, Account account) {
super();
this.operationDate = operationDate;
this.amount = amount;
this.typeOperation = typeOperation;
this.account = account;
}
public long getNumberOperation() {
return numberOperation;
}
public void setNumberOperation(long numberOperation) {
this.numberOperation = numberOperation;
}
public Date getOperationDate() {
return operationDate;
}
public void setOperationDate(Date operationDate) {
this.operationDate = operationDate;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getTypeOperation() {
return typeOperation;
}
public void setTypeOperation(String typeOperation) {
this.typeOperation = typeOperation;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
Here, we are creating an Entity
SavingsAccount.java This object extends Account
src/main/java/com/bank/model/SavingsAccount.java):
package com.bank.modal;
import java.util.Date;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("SA")
public class SavingsAccount extends Account {
/**
*
*/
private static final long serialVersionUID = 1L;
private double tax;
public SavingsAccount() {
super();
}
public SavingsAccount(String code, Date createDate, double balance, Client client, double tax) {
super(code, createDate, balance, client);
this.tax = tax;
}
public double getTax() {
return tax;
}
public void setTax(double tax) {
this.tax = tax;
}
}
Here, we are creating an Entity
StandingAccount.java This object extends Account
src/main/java/com/bank/model/StandingAccount.java):
package com.bank.modal;
import java.util.Date;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("CA")
public class StandingAccount extends Account {
/**
*
*/
private static final long serialVersionUID = 1L;
private double loan;
public StandingAccount() {
super();
}
public StandingAccount(String code, Date createDate, double balance, Client client, double loan) {
super(code, createDate, balance, client);
this.loan = loan;
}
public double getLoan() {
return loan;
}
public void setLoan(double loan) {
this.loan = loan;
}
}
Here, we are creating an Entity
Credit.java This object extends Operation
src/main/java/com/bank/model/Credit.java):
package com.bank.modal;
import java.util.Date;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("w")
public class Withdraw extends Operation {
/**
*
*/
private static final long serialVersionUID = 1L;
public Withdraw() {
super();
}
public Withdraw(Date operationDate, double amount, String typeOperation, Account account) {
super(operationDate, amount, typeOperation, account);
}
}
Spring Data JPA Projections
When using Spring Data JPA to implement the persistence layer, the repository typically returns one or more instances of the root class. However, more often than not, we don't need all the properties of the returned objects.
In such cases, it may be desirable to retrieve data as objects of customized types. These types reflect partial views of the root class, containing only properties we care about. This is where projections come in handy.
We need to create these interface dao
-> AccountDao
-> ClientDao
-> OperationDao
Here, we are creating a AccountDao interface
src/main/java/com/bank/dao/AccountDao.java):
package com.bank.dao;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import com.bank.modal.Account;
public interface AccountDao extends JpaRepository<Account, Integer> {
Optional<Account> findByCode(String code);
}
Here, we are creating a ClientDao interface
src/main/java/com/bank/dao/ClientDao.java):
package com.bank.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.bank.modal.Client;
public interface ClientDao extends JpaRepository<Client, Long> {
}
Here, we are creating a OperationDao interface
src/main/java/com/bank/dao/OperationDao.java):
package com.bank.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.bank.modal.Operation;
public interface OperationDao extends JpaRepository<Operation, Long> {
@Query("select o from Operation o where o.account.id=:x order by o.operationDate desc")
public List<Operation> checkingAccount(@Param("x") int id);
}
The services
Service Components are the class file which contains @Service annotation. These class files are used to write business logic in a different layer, separated from @RestController class file. The logic for creating a service component class file is shown here
We will create one interface in service package:
-> BankService
Here, we are creating a BankService
src/main/java/com/bank/model/BankService.java):
package com.bank.service;
import java.util.List;
import com.bank.modal.Account;
import com.bank.modal.Client;
import com.bank.modal.Operation;
import com.bank.modal.SavingsAccount;
import com.bank.modal.StandingAccount;
public interface BankService {
List<Operation> checkingAccount(int code);
Operation deposit(int code, double amount);
Operation debit(int code, double amount);
Operation transfer(int code1, int code2, Operation operation);
void debitOperation(int code, double amount);
void depositOperation(int code, double amount);
Client loginClient(Client client);
Client updateClient(Client client, long id);
StandingAccount addStandingAccount(StandingAccount standingAccount, long id);
SavingsAccount addSavingsAccount(SavingsAccount savingsAccount, long id);
StandingAccount editStandingAccount(StandingAccount standingAccount, int id);
SavingsAccount editSavingsAccount(SavingsAccount savingsAccount, int id);
List<Operation> findWithdraws(int id);
List<Operation> findCredits(int id);
List<Client> findClients();
Client findClient(long id);
List<Account> findStandingAccountAccounts(long id);
List<Account> findSavingsAccountAccounts(long id);
List<Account> findAccountsForClient(long id);
}
The managers classes implementation
An impl class is usually a class that implements the behaviour described by one of these interfaces. While the internal implementation class, With transactions configured, we can now annotation a bean with @Transactional and @Service either at the class or method level. Then conversion Entity to DTO. This is stands for Data Transfer Object and is a simple Plain Old Java Object which contains class properties and getters and settings methods for accessing those properties.
We will create ont class in the impl package
-> BankServiceImpl
Here, we are creating a BankServiceImpl
src/main/java/com/bank/service/BankServiceImpl.java):
package com.bank.service;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.bank.dao.AccountDao;
import com.bank.dao.ClientDao;
import com.bank.dao.OperationDao;
import com.bank.modal.Account;
import com.bank.modal.Client;
import com.bank.modal.Credit;
import com.bank.modal.StandingAccount;
import com.bank.modal.Operation;
import com.bank.modal.SavingsAccount;
import com.bank.modal.Withdraw;
@Transactional
@Component
public class BankServiceImp implements BankService {
@Autowired
private AccountDao accountDao;
@Autowired
private OperationDao operationDao;
@Autowired
private ClientDao clientDao;
@Override
public List<Operation> checkingAccount(int code) {
return operationDao.checkingAccount(code);
}
@Override
public Operation deposit(int code, double amount) {
String deposit = "deposit";
Account account = accountDao.findById(code).orElse(null);
Credit credit = new Credit(new Date(), amount, deposit, account);
account.setBalance(account.getBalance() + amount);
accountDao.save(account);
return operationDao.save(credit);
}
@Override
public Operation debit(int code, double amount) {
String debit = "debit";
Account account = accountDao.findById(code).orElse(null);
double checkout = 0;
if (account instanceof StandingAccount) {
checkout = ((StandingAccount) account).getLoan();
}
if (account.getBalance() + checkout < amount) {
throw new RuntimeException("Insufficient balance");
}
Withdraw withdraw = new Withdraw(new Date(), amount, debit, account);
account.setBalance(account.getBalance() - amount);
accountDao.save(account);
return operationDao.save(withdraw);
}
@Override
public Operation transfer(int code1, int code2, Operation operation) {
if (code1 == code2) {
throw new RuntimeException("Cannot transfer to the same account ");
}
deposit(code1, operation.getAmount());
debit(code2, operation.getAmount());
return operationDao.save(operation);
}
@Override
public void depositOperation(int code, double amount) {
Account account = accountDao.findById(code).orElse(null);
deposit(account.getId(), amount);
}
@Override
public Client loginClient(Client client) {
List<Client> clients = clientDao.findAll();
if (clients.size() == 0) {
client.setAdmin(true);
}
for (Client client2 : clients) {
if (client.getUsername().equals(client2.getUsername())) {
client2.setUsername(client2.getUsername());
return clientDao.save(client2);
}
}
return clientDao.save(client);
}
@Override
public StandingAccount addStandingAccount(StandingAccount standingAccount, long id) {
char[] chars = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();
StringBuilder sb = new StringBuilder(6);
Random random = new Random();
for (int i = 0; i < 6; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
Client client = clientDao.findById(id).orElse(null);
standingAccount.setCreateDate(new Date());
standingAccount.setCode(output);
client.addAccount(standingAccount);
return accountDao.save(standingAccount);
}
@Override
public void debitOperation(int code, double amount) {
Account account = accountDao.findById(code).orElse(null);
debit(account.getId(), amount);
}
@Override
public SavingsAccount addSavingsAccount(SavingsAccount savingsAccount, long id) {
char[] chars = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();
StringBuilder sb = new StringBuilder(6);
Random random = new Random();
for (int i = 0; i < 6; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
Client client = clientDao.findById(id).orElse(null);
savingsAccount.setCreateDate(new Date());
savingsAccount.setCode(output);
client.addAccount(savingsAccount);
return accountDao.save(savingsAccount);
}
@Override
public List<Operation> findWithdraws(int id) {
List<Operation> operations = accountDao.getOne(id).getOperations().stream().filter(w -> w instanceof Withdraw)
.collect(Collectors.toList());
return operations;
}
@Override
public List<Operation> findCredits(int id) {
List<Operation> operations = accountDao.getOne(id).getOperations().stream().filter(c -> c instanceof Credit)
.collect(Collectors.toList());
return operations;
}
@Override
public List<Client> findClients() {
return clientDao.findAll();
}
@Override
public Client findClient(long id) {
return clientDao.findById(id).orElse(null);
}
@Override
public Client updateClient(Client client, long id) {
Client client2 = clientDao.findById(id).orElse(null);
client2.setPassword(client.getPassword());
client2.setUsername(client.getUsername());
client2.setEmail(client.getEmail());
client2.setName(client.getName());
return clientDao.save(client2);
}
@Override
public List<Account> findStandingAccountAccounts(long id) {
List<Account> accounts = clientDao.getOne(id).getAccounts().stream().filter(s -> s instanceof StandingAccount)
.collect(Collectors.toList());
return accounts;
}
@Override
public List<Account> findSavingsAccountAccounts(long id) {
List<Account> accounts = clientDao.getOne(id).getAccounts().stream().filter(s -> s instanceof SavingsAccount)
.collect(Collectors.toList());
return accounts;
}
@Override
public List<Account> findAccountsForClient(long id) {
Client client = clientDao.findById(id).orElse(null);
return client.getAccounts();
}
@Override
public StandingAccount editStandingAccount(StandingAccount standingAccount, int id) {
StandingAccount standingAccount2 = (StandingAccount) accountDao.findById(id).orElse(null);
standingAccount2.setLoan(standingAccount.getLoan());
standingAccount2.setBalance(standingAccount.getBalance() + standingAccount.getLoan());
return accountDao.save(standingAccount2);
}
@Override
public SavingsAccount editSavingsAccount(SavingsAccount savingsAccount, int id) {
SavingsAccount savingsAccount2 = (SavingsAccount) accountDao.findById(id).orElse(null);
savingsAccount2.setTax(savingsAccount.getTax());
savingsAccount2.setBalance(savingsAccount2.getBalance() - savingsAccount.getTax());
return accountDao.save(savingsAccount2);
}
}
@RestController API
@RestController is a convenience annotation for creating Restful controllers. It is a specialization of @Component and is autodetected through classpath scanning. It adds the @Controller and @ResponseBody annotations. It converts the response to JSON or XML. It does not work with the view technology, so the methods cannot return ModelAndView. It is typically used in combination with annotated handler methods based on the @RequestMapping annotation.
We will create one class in controller package:
-> BankController
In The Controller We'll inject this bean into the controller bean using @Autowired on the field definition: We need to add map requests with request mapping annotations e.g. @RequestMapping, @GetMapping and @PostMapping
src/main/java/com/bank/controller/BankController.java):
package com.bank.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.bank.dao.AccountDao;
import com.bank.modal.Account;
import com.bank.modal.Client;
import com.bank.modal.Operation;
import com.bank.modal.SavingsAccount;
import com.bank.modal.StandingAccount;
import com.bank.service.BankService;
@RestController
@RequestMapping(value = "/api")
@CrossOrigin(origins = "*")
public class BankController {
@Autowired
private BankService bankService;
@Autowired
private AccountDao accountDao;
@GetMapping("/checkingAccount/{code}")
List<Operation> checkingAccount(@PathVariable int code) {
return bankService.checkingAccount(code);
}
@PostMapping("/depositOperation/{code}")
void depositOperation(@PathVariable int code, @RequestBody Operation operation) {
bankService.depositOperation(code, operation.getAmount());
}
@PostMapping("/saveClient")
Client loginClient(@RequestBody Client client) {
return bankService.loginClient(client);
}
@PostMapping("/addStandingAccount/{id}")
StandingAccount addStandingAccount(@RequestBody StandingAccount standingAccount, @PathVariable long id) {
return bankService.addStandingAccount(standingAccount, id);
}
@PostMapping("/addSavingsAccount/{id}")
SavingsAccount addSavingsAccount(@RequestBody SavingsAccount savingsAccount, @PathVariable long id) {
return bankService.addSavingsAccount(savingsAccount, id);
}
@PostMapping("/debitOperation/{code}")
void debitOperation(@PathVariable int code, @RequestBody Operation operation) {
bankService.debitOperation(code, operation.getAmount());
}
@GetMapping("/findWithdraws/{id}")
List<Operation> findWithdraws(@PathVariable int id) {
return bankService.findWithdraws(id);
}
@GetMapping("/findCredits/{id}")
List<Operation> findCredits(@PathVariable int id) {
return bankService.findCredits(id);
}
@PostMapping("/transfer/{code1}/{code2}")
Operation transfer(@PathVariable int code1, @PathVariable int code2, @RequestBody Operation operation) {
return bankService.transfer(code1, code2, operation);
}
@GetMapping("/findClients")
List<Client> findClients() {
return bankService.findClients();
}
@GetMapping("/findClient/{id}")
Client findClient(@PathVariable long id) {
return bankService.findClient(id);
}
@PutMapping("/updateClient/{id}")
Client updateClient(@RequestBody Client client, @PathVariable long id) {
return bankService.updateClient(client, id);
}
@GetMapping("/findStandingAccountAccounts/{id}")
List<Account> findStandingAccountAccounts(@PathVariable long id) {
return bankService.findStandingAccountAccounts(id);
}
@GetMapping("/findSavingsAccountAccounts/{id}")
List<Account> findSavingsAccountAccounts(@PathVariable long id) {
return bankService.findSavingsAccountAccounts(id);
}
@GetMapping("/findAccountById/{id}")
Account findAccountById(@PathVariable int id) {
return accountDao.findById(id).orElse(null);
}
@GetMapping("/findAccountsForClient/{id}")
List<Account> findAccountsForClient(@PathVariable long id) {
return bankService.findAccountsForClient(id);
}
@PostMapping("/editStandingAccount/{id}")
StandingAccount editStandingAccount(@RequestBody StandingAccount standingAccount, @PathVariable int id) {
return bankService.editStandingAccount(standingAccount, id);
}
@PostMapping("/editSavingsAccount/{id}")
SavingsAccount editSavingsAccount(@RequestBody SavingsAccount savingsAccount, @PathVariable int id) {
return bankService.editSavingsAccount(savingsAccount, id);
}
}
BankApplication
@BookStoreApplication and its use in a simple Spring Boot application. We use the @SpringBootApplication annotation in our Application or Main class to enable a host of features, e.g. Java-based Spring configuration, component scanning, and in particular for enabling Spring
src/main/java/com/bank/BankApplication.java):
package com.bank;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BankApplication {
public static void main(String[] args) {
SpringApplication.run(BankApplication.class, args);
System.out.println("App started....");
}
}
Conclusion
Now we have an overview of Spring Boot example when building a @RestController API.
We also take a look at client-server architecture for REST API using Spring Web MVC & Spring Data JPA, as well, we are gooing to continue with Ionic project structure for building a front-end app to make HTTP requests and consume responses.