Programming & Development / April 18, 2025

Using a ContactRequest DTO for Clean Contact Form Handling in Spring Boot

Spring Boot ContactRequest DTO contact form backend Java JPA DTO service Spring Boot REST DTO example contact request data transfer object service layer Spring Boot Spring clean architecture

When building a contact form backend in Spring Boot, it's good practice to separate your internal entity from incoming API requests. This can be done using a DTO (Data Transfer Object) โ€” in our case, a ContactRequest. In this post, weโ€™ll walk through creating a JPA-backed contact service that uses a ContactRequest DTO for request handling.

๐Ÿ“ฉ Step 1: Define the ContactRequest DTO

The DTO serves as the structure for incoming request payloads.

java

public class ContactRequest {
    private String name;
    private String email;
    private String subject;
    private String message;

    // Getters and Setters
}

๐Ÿ“ฆ Step 2: Define the Contact Entity

This entity will be stored in the database.

java

import javax.persistence.*;

@Entity
public class Contact {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;
    private String subject;
    private String message;

    // Getters and Setters
}

๐Ÿ’พ Step 3: Create a JPA Repository

java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ContactRepository extends JpaRepository<Contact, Long> {
}

โš™๏ธ Step 4: Define the Service Interface

Update the service interface to accept the ContactRequest DTO for create and update operations.

java

import java.util.List;

public interface ContactService {
    Contact saveContact(ContactRequest contactRequest);
    List<Contact> getAllContacts();
    Contact getContactById(Long id);
    Contact updateContact(Long id, ContactRequest contactRequest);
    void deleteContact(Long id);
}

๐Ÿง  Step 5: Implement the Service Logic

Hereโ€™s the full implementation that maps between the DTO and entity:

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ContactServiceImpl implements ContactService {

    @Autowired
    private ContactRepository contactRepository;

    @Override
    public Contact saveContact(ContactRequest contactRequest) {
        Contact contact = new Contact();
        contact.setName(contactRequest.getName());
        contact.setEmail(contactRequest.getEmail());
        contact.setSubject(contactRequest.getSubject());
        contact.setMessage(contactRequest.getMessage());
        return contactRepository.save(contact);
    }

    @Override
    public List<Contact> getAllContacts() {
        return contactRepository.findAll();
    }

    @Override
    public Contact getContactById(Long id) {
        return contactRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Contact not found with id: " + id));
    }

    @Override
    public Contact updateContact(Long id, ContactRequest contactRequest) {
        Contact contact = getContactById(id);
        contact.setName(contactRequest.getName());
        contact.setEmail(contactRequest.getEmail());
        contact.setSubject(contactRequest.getSubject());
        contact.setMessage(contactRequest.getMessage());
        return contactRepository.save(contact);
    }

    @Override
    public void deleteContact(Long id) {
        Contact contact = getContactById(id);
        contactRepository.delete(contact);
    }
}

๐ŸŒ Step 6: Add a REST Controller

This is how your controller can use the ContactRequest for handling HTTP requests.

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/contacts")
public class ContactController {

    @Autowired
    private ContactService contactService;

    @PostMapping
    public ResponseEntity<Contact> createContact(@RequestBody ContactRequest contactRequest) {
        return ResponseEntity.ok(contactService.saveContact(contactRequest));
    }

    @GetMapping
    public ResponseEntity<List<Contact>> getAllContacts() {
        return ResponseEntity.ok(contactService.getAllContacts());
    }

    @GetMapping("/{id}")
    public ResponseEntity<Contact> getContactById(@PathVariable Long id) {
        return ResponseEntity.ok(contactService.getContactById(id));
    }

    @PutMapping("/{id}")
    public ResponseEntity<Contact> updateContact(@PathVariable Long id, @RequestBody ContactRequest contactRequest) {
        return ResponseEntity.ok(contactService.updateContact(id, contactRequest));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteContact(@PathVariable Long id) {
        contactService.deleteContact(id);
        return ResponseEntity.noContent().build();
    }
}

๐Ÿšจ Step 7: Add Exception Handling (Optional but Recommended)

java

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

โœ… Summary

By introducing a ContactRequest DTO, you've added an abstraction layer between your REST API and your database, making your code more flexible and easier to maintain. This clean approach enables:

  • Separation of concerns
  • Future-proofing against changes in internal data structures
  • Better validation and transformation support



Comments

No comments yet

Add a new Comment

NUHMAN.COM

Information Technology website for Programming & Development, Web Design & UX/UI, Startups & Innovation, Gadgets & Consumer Tech, Cloud Computing & Enterprise Tech, Cybersecurity, Artificial Intelligence (AI) & Machine Learning (ML), Gaming Technology, Mobile Development, Tech News & Trends, Open Source & Linux, Data Science & Analytics

Categories

Tags

©{" "} Nuhmans.com . All Rights Reserved. Designed by{" "} HTML Codex