티스토리 뷰

728x90
반응형

 

 

 

지난 글에서 스프링 MVC(Model - View - Controller)의 구성요소와 작동방식에 대해 알아봤다.

 

https://gnidinger.tistory.com/464 

 

[Spring]Spring MVC

이전 글에서 스프링의 모듈 구조에 대해 본 적이 있다. 출처: https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/overview.html 2. Introduction to Spring Framework Sprin..

gnidinger.tistory.com

간단하게 요약하자면 스프링 MVC는 위 아키텍처에서 클라이언트의 요청을 받아들이는 계층,

 

Presentation Layer(=API Layer) 영역을 세분화한 것이며

 

출처: https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/overview.html

 

2. Introduction to Spring Framework

Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so you can focus on your application. Spring enables you to build applications from "plain old Java o

docs.spring.io

스프링 프레임워크의 웹(Web) 계층을 담당하는 모듈 중 서블릿(Servlet) API를 기반으로 클라이언트의 요청을 처리하는

 

spring-webmvc모듈이기도 하며

 

DispatcherServlet 객체를 프론트 컨트롤러로 둔 프론트 컨트롤러 패턴으로 동작한다.

 

지금부터 이어지는 글에선 커피 판매 앱에 대한 Presentation Layer(=API Layer) 영역을 실제로 구현해볼 것이며,

 

이를 위해 알아야 할 키워드는 Controller와 DTO(Data Transfer Object)이다.

 

참고로 각 영역에 해당하는 컴포넌트 자동 등록 애너테이션은 아래와 같다.

 

  •   @Controller - Presentation Layer(=API Layer)
  •   @Service - Application Layer(=Service Layer, Business Layer)
  •   @Repsitory - Data Access Layer

이 글에서는 먼저 Controller 클래스의 구조 생성 및 설계에 대해 알아본다.

 


구조 생성

 

가장 먼저 해야할 일은 생성한 프로젝트에 자바 패키지 구조를 잡는 것이다.

 

스프링 부트 기반의 앱에서 주로 사용되는 패키지 구조는 두 가지가 있는데,

 

  • 기능 기반 패키지 구조(package-by-feature)
  • 계층 기반 패키지 구조(package-by-layer)

가 그것이다.

 

  • 기능 기반 패키지 구조(package-by-feature)

먼저 기능 기반 패키지 구조는 말 그대로 패키지를 기능에 따라 나누는 것을 말한다.

 

따라서 한 패키지 안에 하나의 기능을 완성하기 위한 계층별 클래스가 모여있다.

 

위 그림에선 패키지를 커피 기능과 멤버 기능으로 나눈 것을 확인할 수 있다.

 

위에서 짧게 언급 했듯이 ‘Controller, DTO’ 클래스는 API 계층에, ‘Coffee, Member, Service’ 는 비즈니스 계층에 해당되며

 

Repository 클래스는 데이터 액세스 계층에 해당된다.

 

  • 계층 기반 패키지 구조(package-by-layer)

계층 기반 패키지 구조는 패키지를 하나의 계층(Layer)에 따라 나눠 관리하는 구조를 말한다.

 

각 계층에 따라 패키지를 구성해 클래스를 위치시킨 것을 확인할 수 있다.

 

위 두가지 패키지 구조는 애플리케이션의 요구 사항이나 특성에 따라서 상황에 맞게 적절하게 사용되지만,

 

Spring Boot에서는 기능 기반 패키지 구조 사용을 권장하고 있다.

 

그 이유는 테스트와 리팩터링이 용이하고, 마이크로 서비스 시스템으로의 분리가 상대적으로 용이하기 때문이라고 한다.

 

 

Controller 클래스의 설계

 

지난 번 글에서도 살펴봤지만 컨트롤러는 요청을 처리하는 로직을 담고 있으며 필요한 로직을 호출하는 역할을 한다.

 

따라서 이런 역할을 하는 컨트롤러를 설계에는 당연히 클라이언트의 요청과 그 처리 기능에 대한 고민이 담겨야 한다.

 

그렇다면 커피 주문 애플리케이션의 기능 요구 사항은 어떤 것들이 있을까? 대략적으로 아래와 같을 것이다.

 

  • 주인이 커피 정보를 관리하는 기능

    • 커피 정보 등록 기능
    • 등록한 커피 정보 수정 기능
    • 등록한 커피 정보 삭제 기능
    • 등록한 커피 정보 조회 기능
  • 고객이 커피 정보를 조회하는 기능
  • 고객이 커피를 주문하는 기능

    • 커피 주문 등록 기능
    • 커피 주문 취소 기능
    • 커피 주문 조회 기능
  • 고객이 주문한 커피를 주인이 조회하는 기능

    • 주문 조회 기능
    • 고객에게 전달 완료한 커피에 대한 주문 완료 처리 기능

그렇다면 이 기능을 구현하기 위해선 몇 개의 컨트롤러 객체가 필요할까?

 

REST API 기반의 애플리케이션에서는 애플리케이션이 제공해야 될 기능을 리소스(Resource)로 분류한다.

 

위 기능을 구현하기 위한 리소스는 아래와 같은 구성이 될 것이다.

 

따라서 총 세 개의 컨트롤러 클래스를 작성하면 된다.

 

특이한 점은 고객과 주인의 기능을 따로 분리하지 않고 회원으로 묶었다는 것인데

 

둘을 완전히 분리한다면 인증 프로세스가 복잡해질 수 있기 때문이다.

 

따라서 고객과 주인을 회원 리소스에 포함시키고, 둘 사이의 ROLE을 통해 기능을 구분하는 것이 편하다고 한다.

 

  • 엔트리 포인트(Entrypoint) 클래스

엔트리 포인트(Entrypoint) 클래스란 Spring Boot 기반의 애플리케이션이 정상적으로 실행되기 위해 필요한

 

main() 메서드가 포함된 클래스를 말한다.

 

https://start.spring.io/를 통해 생성한 프로젝트엔 이미 엔트리 포인트 클래스가 작성되어 있으며,

 

그 모양은 아래와 같다.

package com.gnidinger;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // (1)
public class SpringMVCPractice {

	public static void main(String[] args) {
		SpringApplication.run(SpringMVCPractice.class, args); // (2)
	}

}

(1) @SpringBootApplication

 

  • 자동 구성 활성화
  • @Component가 붙은 클래스를 찾아 스프링 빈으로 등록(@ComponentScan)
  • @Configuration 붙은 클래스를 찾아 @Bean이 붙은 메서드의 리턴 클래스와 함께 스프링 빈으로 등록

 

(2) SpringApplication.run(SpringMVCPractice.class, args);

 

Spring 애플리케이션을 부트스트랩(Bootstrap)*하고, 실행하는 역할을 한다.

 

*부트스트랩(Bootstrap) - 애플리케이션 실행 전 설정 작업을 수행하여 실행 가능한 애플리케이션으로 만드는 단계

 

  • Controller 구조 작성

Member, Coffee, Order에 대한 컨트롤러 구조를 작성한다.

 

아래에 작성되는 컨트롤러는 아직 미완성이며, 다음 글에서 핸들러 메서드를 채워주어야 한다.

 

  • MemberController
package com.gnidinger.member;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController // (1)
@RequestMapping("/v1/members") // (2)
public class MemberController {
}

(1) @RestController

 

  • 해당 클래스가 REST API의 리소스(Resource)를 처리하기 위한 API 엔드포인트로 동작함을 선언
  • @RestController 추가된 클래스는 애플리케이션 로딩 , Spring Bean으로 등록됨

 

(2) @RequestMapping

 

  • 클라이언트의 요청과 요청을 처리하는 핸들러 메서드(Handler Method)를 매핑
  • ("/v1/members")와 같이 클래스 전체에 사용되는 공통 URL을 설정

나머지 두 개의 컨트롤러도 같은 방식으로 만들어주면 된다.

 

  • CoffeeController
package com.gnidinger.coffee;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
@RequestMapping("/v1/coffees")
public class CoffeeController {
}

 

  • OrderController
package com.gnidinger.order;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
@RequestMapping("/v1/orders")
public class OrderController {
}
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함