thug_choonsik 춘식이 주특기: 삼촌들 용돈 뺏기

Controller, Service, Repository

» spring

layered architecture는 소프트웨어 개발에서 자주 사용되는 아키텍처이다. 소프트웨어를 여러 계층으로 나누어 각 계층이 독립적으로 개발되고, 계층 간의 의존성이 최소화되도록 설계하는 방식이다. 계층 간의 의존성이 최소화되기 때문에, 계층 간의 변경이 다른 계층에 영향을 줄일 수 있고 각 계층의 책임과 역할을 명확하게 할 수 있다.

스프링의 경우, 주로 Controller, Service, Repository라는 세 가지 계층으로 나누어 개발한다. 각 계층의 역할과 책임을 간단히 설명하자면 다음과 같다.


Controller

HTTP 요청을 주고 받는 역할을 하는 프레젠테이션 계층이다. 엔드포인트와 HTTP 메서드를 기반으로 요청을 처리하며, 클라이언트로부터 받은 요청을 적절한 서비스 계층에 전달하며, 서비스 계층으로부터 받은 결과를 클라이언트에게 응답하는 역할을 한다. @Controller 혹은 @RestController 어노테이션을 사용하여 정의할 수 있다.

@RestController
@RequestMapping("/api/books")
public class BookController {
    private final BookService bookService;

    @Autowired
    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        return bookService.save(book);
    }
}


Service

비즈니스 로직을 수행하는 역할을 하는 계층이다. Repository로부터 데이터를 가져와서 가공하고 적절하게 처리한 후, Controller에게 전달한다. @Service 어노테이션을 사용하여 정의할 수 있다.

@Service
public class BookService {
    private final BookRepository bookRepository;

    @Autowired
    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public Book save(Book book) {
        return bookRepository.save(book);
    }
}

// Entity
public class Book {
    private Long id; // Entity 식별자
    private String title;
    private Author author; // VO

    public Book(Long id, String title, Author author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    public Long getId() {
        return this.id;
    }

    public String getTitle() {
        return this.title;
    }

    public Author getAuthor() {
        return this.author;
    }
}


Repository

영속성을 가지게 하기 위한 인프라(RDBMS 등)와 상호작용할 수 있는 인터페이스를 제공하는 계층이다. 데이터를 영속성 저장소에 저장하고 조회하는 역할을 한다. Spring Data JPA를 사용하면 SQL을 직접 작성하지 않고도 Repository 인터페이스를 통해 데이터를 조작할 수 있다. 이를 통해 특정 데이터베이스에 종속되지 않도록 할 수 있다.

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
    Optional<Book> findByTitle(String title);
}