Delete Operation – REST API

We can build one more REST API that will allow my client application to delete the existing customer and account details.

Requirement

Clients can send the mobileNUmber as a request to the delete API. Based upon the given mobile number, I Will try to load the customer entity details from the database.

From the Customer entity, I’ll be getting customerId. Using customerId, I’m going to delete the records present in both tables, which is inside the accounts and customer because both tables have this common column, which is customerId.

Add abstract method in Service Interface

/**
*
* @param mobileNumber - Input Mobile Number
* @return boolean indicating if the delete of Account details is successful or not
*/
boolean deleteAccount(String mobileNumber);

This is also going to return a boolean value saying if the delete operation is successful or not and it is going to accept the mobile number as an input parameter.

Implementing the method – Service implementation

This is the empty implementation.

/**
* @param mobileNumber - Input Mobile Number
* @return boolean indicating if the delete of Account details is successful or not
*/
@Override
public boolean deleteAccount(String mobileNumber) {

return false;
}

Given the mobileNumber, we first try to get the customer entity details. From the Customer entity, I’ll be getting customerId. Using customerId, I’m going to delete the records present in both tables, which are inside the accounts and customer because both tables have this common column, which is customerId.

Custom Query in AccountsRepository

Write a custom query inside AccountsRepository to delete records based on customerId.

@Repository
public interface AccountsRepository extends JpaRepository<Accounts, Long>
{
Optional<Accounts> findByCustomerId(Long customerId);
void deleteByCustomerId(Long customerId);
}

Since this customerId is not a primary key inside the accounts table, we need to write this method inside the AccountsRepository.

With this my Spring Data JPA Behind the scenes it is going to generate a delete query.

NOTE – With the help of our custom methods, we are trying to change the data inside the database. Whenever you are trying to update or delete with the custom methods that you have written, we need to make sure we are mentioning two annotations on top of these abstract methods.

These two annotations are : 

  1. @Transactional and 
  2. @Modifying

@Modifying will tell the Spring Data JPA framework that this method is going to modify the data. So that’s why please execute the query of this method inside a Transaction. That’s why we are mentioning @Transactional annotation.

@Repository
public interface AccountsRepository extends JpaRepository<Accounts, Long> {
Optional<Accounts> findByCustomerId(Long customerId);

@Transactional
@Modifying
void deleteByCustomerId(Long customerId);
}

When my Spring Data JPA runs my query inside a Transaction and if there is some error happens at the runtime, any partial change of data that is resulted due to the queries will be rolled back because the entire transaction will be rolled back by the Spring Data JPA and we are in safe hands.

→ We need to mention these annotations specifically for custom query methods only.

Complete the service layer implementation 

/**
* @param mobileNumber - Input Mobile Number
* @return boolean indicating if the delete of Account details is successful or not
*/
@Override
public boolean deleteAccount(String mobileNumber) {
Customer customer =
customerRepository.findByMobileNumber(mobileNumber)
.orElseThrow(
() -> new ResourceNotFoundException("Customer", "mobileNumber",
mobileNumber)
);
accountsRepository.deleteByCustomerId(customer.getCustomerId());
customerRepository.deleteById(customer.getCustomerId());
return true;
}

Adding REST API in Controller layer

Code – 

@DeleteMapping("/delete")
public ResponseEntity<ResponseDto> deleteAccountDetails(
@RequestParam String mobileNumber)
{
boolean isDeleted = service.deleteAccount(mobileNumber);
if(isDeleted) {
return ResponseEntity
.status(HttpStatus.OK)
.body(new ResponseDto(
AccountsConstants.STATUS_200,
AccountsConstants.MESSAGE_200));
}else{
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ResponseDto(
AccountsConstants.STATUS_500,
AccountsConstants.MESSAGE_500));
}
}

We use @DeleteMapping annotation to map the HTTP DELETE method code.

Build and Deploy

The application is started at port number 8080.

Using Postman, you can invoke the REST APIs.

Sending some wrong data – 

Fetch the record, it won’t be available as it has already been deleted.