꿈소년의 개발 이야기

[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 03. 인메모리 기반의 To-Do 리스트 REST API 서버 만들기 본문

Do it 스터디!/스프링 부트 개발자 온보딩 가이드 스터디!

[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 03. 인메모리 기반의 To-Do 리스트 REST API 서버 만들기

fogthegreat 2026. 4. 3. 20:11
반응형

DAY 3

🔖 오늘 읽은 범위 :

🌱공부 내용: Chapter 03. 인메모리 기반의 To-Do 리스트 REST API 서버 만들기
👢쪽수: p.58- p.103


프로젝트 스캐폴드 생성 및 다운로드

옵션 설명
dependencies web REST API 서버 개발에 필요한 의존성 추가.
org.springframework.boot 추가.
이 의존성은 서블릿 컨테이너인 톰캣을 내장하고, 스프링 MVC 기반 앱, REST API 서버 개발에 필요한 클래스 라이브러리 제공함.
javaVersion 21 프로젝트에서 사용할 자바 버전 설정.
type gradle-project 빌드 도구로 Gradle 설정.
bootVersion 3.3.1 → 3.5.0 스프링 부트 버전 설정.
→ 2025년 12월 30일 기준 3.5.0 버전으로 해야 가능함.
groupId com.asdf 프로젝트 그룹 ID.
조직이나 회사의 도메인 이름 역순으로 작성.
패키지 네임스페이스를 구성하는 데 사용함.
’com.asdf’ 는 ‘asdf.com’ 도메인을 가진 조직의 프로젝트임.
name todo 프로젝트 이름.
프로젝트 식별하는데 사용함.
프로젝트 메인 디렉토리와 연관됨.
artifactId todo-in-memory 프로젝트 아티팩트 ID.
프로젝트 고유 식별자.
프로젝트 이름과 유사하게 설정함.
생성되는 JAR 파일 등의 이름으로 사용됨.
packageName com.asdf.todo 기본 패키지 이름.
패키지 이름은 코드의 네임스페이스를 정의함.
충돌 방지 역할.

WSL2 터미널에서 스프링 이니셜라이저 통해서 스프링 부트 프로젝트 템플릿 압축 파일 다운로드

curl https://start.spring.io/starter.zip \
        -d dependencies=web \
        -d javaVersion=21 \
        -d type=gradle-project \
        -d bootVersion=3.3.1 \
        -d groupId=com.asdf \
        -d name=todo \
        -d artifactId=todo-in-memory \
        -d packageName=com.asdf.todo \
        -o todo-in-memory.zip
  • -d : curl 명령어가 POST 로 보낼 본문의 내용을 구축함.
  • -o : 오브젝트 생성.

압축 받은 파일 해제

unzip todo-in-memory.zip -d todo-in-memory

Intellij IDEA 프로젝트 초기화

프로젝트 열기로 해당 폴더 열기.

  • WSL2 인스턴스 경로: \wsl$\Ubuntu-24.04

윈도우에서 WSL2 파일 시스템 접근하기

  • \wsl$ : WSL 네트워크 파일 시스템을 나타내는 특수 네트워크 경로. 윈도우즈에서 네트워크 드라이브처럼 접근할 수 있게 함.
  • Ubuntu-24.04 : 특정 WSL2 배포판 이름.

상호 호환되어 작업 가능함.

Microsoft Defender 예외 처리 추가

예외 추가

  • \wsl.localhost\Ubuntu-24.04\home{리눅스사용자}\eog-springboot3\todo-in-memory
  • C:\Users{윈도우즈사용자}\AppData\Roaming\JetBrains\IdeaC2024.2

애플리케이션 패키지 및 소스 코드 파일 생성하기

생성할 패키지 목록

경로 패키지
/src/main/java/ com.asdf.todo.config
com.asdf.todo.controller
com.asdf.todo.model
com.asdf.todo.repository
com.asdf.todo.service
/src/test/java com.asdf.todo.controller
com.asdf.todo.service

API 서버 구현

구성요소

  • 모델
  • 리포지토리 빈
  • 관리 서비스 빈
  • REST 컨트롤러 빈
  • API 문서화를 위한 OpenAPI 빈

웹 레이어

REST 컨트롤러 빈

서비스 레이어

관리 서비스 빈

리포지토리 레이어

리포지토리 빈

서비스 와 리포지토리 레이어 사이에 위치한

모델

Todo모델 정의

모델 클래스. Lombok 라이브러리 사용하여 생성자, Getter, Setter 등을 자동 생성함.

Lombok annotation

  • @Data
  • @NoArgsConstructor
  • @AllArgsConstructor
  • @NotNull

Todo 리스트 리포지토리 구현

리포지토리 ⇒ 데이터에 접근하는 계층을 추상화하여 데이터 저장소와의 상호 작용을 처리함.

기능 구현

  • Todo 항목 저장, 조회, 수정, 삭제하는 CRUD(Create, Read, Update, Delete)
  • AtomicLong을 사용하여 Todo 항목 고유 ID 자동 생성.

리포지토리 빈 생성 ⇒ @Repository 애너테이션 붙이기.

스프링이 자동으로 해당 클래스를 리포지토리 빈으로 관리함. 다른 빈이 이 리포지토리 빈을 사용할 수 있도록 함.

Todo 리스트 관리 서비스 빈 구현

서비스 빈 ⇒ 컨트롤러와 리포지토리 사이에 비즈니스 로직을 처리하는 계층.

리포지토리와 상호 작용하여 데이터 조회 및 저장을 처리함.

주요 애노테이션

  • @Service

    서비스 역할을 하는 스프링 빈임을 나타냄.

  • @AutoWired

    스프링이 자동으로 의존성 주입을 수행하게 함.

    • 생성자 주입 ⇒ 불변성과 테스트 용이성을 높여준다는 장점.
    • 필드 주입 ⇒ 간결하나, 테스트 시 모킹이 어렵다.
    • 세터 주입 ⇒ 필요할 경우에 의존성을 변경할 수 있는 유연성 제공함.

서비스의 생성자는 스프링 프레임워크가 호출함.

스프링은 애플리케이션 컨텍스트를 초기화 할 때, @Service 애너테이션이 붙은 클래스를 빈으로 등록함.

그리고 해당 클래스의 생성자를 통해 의존성을 주입함.

스프링의 의존성 주입 과정

  1. 컴포넌트 스캔

    @SpringBootApplication 애너테이션이 붙은 클래스가 위치한 패키지와 그 하위 패키지를 스캔함.

  2. 빈 등록

    @Service, @Repository, @Component 등의 애너테이션이 붙은 클래스를 빈으로 등록함.

  3. 의존성 주입

    빈으로 등록된 클래스의 생성자를 통해서 필요한 의존성 주입.

Todo 리스트 REST 컨트롤러 구현

REST 컨트롤러 빈

  1. 엔드포인트 주소 노출.
  2. 클라이언트 요청 및 입력을 받음.
  3. 서비스 레이어의 메서드를 호출.
  4. 그 결과를 클라이언트에게 반환한다.

주요 스프링 애노테이션

Spring annotation 설명
@RestController 스프링에서 REST 스타일의 웹 API 를 개발할 때 사용하는 애노테이션.
이걸 사용하면 해당 클래스가 REST API 요청을 처리하는 컨트롤러로 스프링이 인식함.
@Controller, @ResponseBody 가 결합한 형태임.
메서드 반환 값을 JSON or XML 형태로 클라이언트에게 반환.
직접 반환 값을 JSON 으로 변경할 필요 없음.
@RequestMapping REST 컨트롤러 클래스 수준의 공통 URL 경로를 지정.
모든 엔드포인트는 같은 URL 로 시작합니다.
@GetMapping HTTP 메서드 GET 매핑.
@PostMapping HTTP 메서드 POST 매핑.
@PutMapping HTTP 메서드 PUT 매핑.
@DeleteMapping HTTP 메서드 DELETE 매핑.
@PathVariable URL 경로의 변수를 매핑하는 데 사용.
경로 상의 변수를 메서드 매개변수로 받아올 수 있음.
@RequestBody HTTP 요청 본문을 메서드 매개변수에 매핑하는데 사용.
주로 POST, PUT 요청에서 클라이언트가 보낸 JSON 데이터를 자바 객체로 변환할 때 사용함.
@Autowired 스프링 의존성 주입 기능을 사용하여 빈을 주입함.
이를 통해서 서비스 빈과 컨트롤러 빈 간의 의존성을 관리할 수 있음.

기능에 영향은 없으나, Swagger 를 이용한 API 문서화에 사용되는 애노테이션

Spring annotation 설명
@Operation API 문서화.
각 메서드에 대해 요약(Summary), 설명(Description)을 작성하여 Swagger UI에서 문서화된 내용을 볼 수 있습니다.
@ApiResponses API 응답 코드를 문서화 하는데 사용됨.
각 응답 코드에 대한 설명을 작성하면 Swagger UI 에서 확인할 수 있음.
@ApiResponse 이상 동일.

API 문서화를 위한 Swagger 설정

OpenAPI 사양을 사용해서 생성.

실제 애플리케이션에서 사용되는 컨트롤러만 문서화 대상. ⇒ @RestController

API 엔드포인트 식별 → 기술된 설명을 바탕으로 요청/응답 스펙과 상태 코드등의 세부 정보를 문서에 반영.

일반적으로 /swagger-ui.html 경로에 접근할 수 있음.

빌드

gradle build -x test

유닛 테스트

검증 테스트.

TestControllerTests

컨트롤러 유닛 테스트.

웹 컨트롤러 빈은 HTTP 입력을 받아 동작하므로 유닛 테스트하기 쉽지 않음.

웹 서버와 웹 컨트롤러가 의존하고 있는 다른 레이어 ⇒ 동작을 모킹하는 방법.

모킹할 수 있는 방법은 @WebMvcTestMockMvc 를 사용함.

  • @WebMvcTest : 컨트롤러와 관련된 빈만 로드함. HTTP 요청과 응답을 시뮬레이션. 서비스, 리포지토리, 컴포넌트 등을 로드하지 않게 함.

  • MockMvc : 스프링 MVC 애플리케이션 요청과 응답을 테스트하기 위한 유틸리티. 애노테이션 ❌

    perform() : HTTP 요청을 실행.

    andExpect() : 상태 코드와 JSON 응답의 특정 필드 확인을 통해 HTTP 응답을 검증.

사용된 애노테이션

  • @ExtendWith(SpringExtension.class)

    Spring TestContext Framework 와 JUnit 5 를 통합하여 스프링 컨텍스트를 사용할 수 있게 함.

  • @WebMvcTest(TodoController.class)

    컨트롤러 레이어 로드함.

  • @MockBean

    모의 객체 Mock 를 스프링 컨텍스트에 주입함. 모킹할 때 사용.

TestServiceTests

TodoService 유닛 테스트.

  • @SpringBootTest

    실제 애플리케이션을 실행할 때 처럼 스프링 애플리케이션 컨텍스트 전체를 로드함.

    서비스 리포지토리, 설정, 빈들이 함께 올라옴. 여러 레이어가 함께 동작하는 통합 테스트 실행.

  • @BeforeEach

    각 테스트 메서드가 실행하기 전에 사전 실행되어 초기 설정을 함.

  • @Test

    해당 메서드가 테스트 메서드임을 나타냄. JUnit 은 이 메서드를 찾아서 테스트 수행함.

스프링 애플리케이션 컨텍스트; 스프링 프레임워크 핵심 개념

Test 실행

gradle test

실행 및 Swagger-UI를 이용한 API 테스트

gradle bootRun

http://localhost:8080/swagger-ui/index.html

테스트 코드의 필요성

  • 작성한 코드가 제대로 동작하는지 확인하려면 앱을 빌드하고 실행해서 API 호출을 해야 함.
  • 스프링 부트 앱은 빌드와 실행에 소요되는 시간이 짧지 않음.
  • 시간이 지날수록 개발되는 규모가 커지면서 이 시간은 결코 줄어들지 않음.
  • 코드 작성 시간보다 전체 개발, 유지보수 시간이 더 늘어날 뿐.
  • 이 시간을 아끼기 위한 조치.
  • 수정을 하고 테스트 코드를 통해서 사이드 이펙트를 미리 확인 차단하는 것.
반응형