5 분 소요

코딩 자율학습단 3주차

11장. HTTP와 REST 컨트롤러

1.REST API

REST는 HTTP URL로 서버의 자원을 명시하고 HTTP 메서드(GET, POST, PATCH/PUT, DELETE)로 해당 자원에 대해 CRUD(생성, 조회, 수정, 삭제)하는 것을 말합니다.

API는 클라이언트가 서버의 자원을 요청할 수 있도록 서버 측에서 제공하는 인터페이스 입니다.

결국 REST API란 REST 기반으로 API를 구현한 것이라고 할 수 있습니다.

2.REST 컨트롤러

REST API로 설계된 URL 요청을 받아 처리하는 컨트롤러입니다. 일반 컨트롤러가 뷰 페이지를 반환한다면 REST 컨트롤러는 JSON이나 텍스트 같은 데이터를 반환합니다.

3.REST 컨트롤러의 특징

  • @RestController 어노테이션을 붙여 선언합니다.
  • 클라이언트의 데이터 조회, 생성, 수정, 삭제 요청을 HTTP 메서드에 맞게 각각 @GetMapping, @PostMapping, @PatchMapping, @DeleteMapping으로 받아 처리합니다.

4.ResponseEntity

REST 컨트롤러의 반환형, 즉 REST API의 응답을 위해 사용하는 클래스입니다. REST API 요청을 받아 응답할 때 이 클래스에 HTTP 상태 코드, 헤더, 본문을 실어 보낼 수 있습니다.

5.HttpStatus

HTTP 상태 코드를 관리하는 클래스로, 다양한 Enum 타입과 관련한 메서드를 가집니다. 상태 코드 200은 HttpStatus.OK, 201은 HttpStatus.CREATED, 400은 HttpStatus.BAD_REQUEST 등으로 관리됩니다.

11장 수행 결과

image image image image

셀프체크 수행 결과

image

12장. 서비스 계층과 트랜잭션

1.서비스

컨트롤러와 리파지터리 사이에 위치하는 계층으로, 서버의 핵심 기능(비즈니스 로직)을 처리하는 순서를 총괄합니다.

클라이언트가 요청을 보내면, 이를 컨트롤러가 받아 서비스로 전달하고, 서비스는 정해진 코드 흐름을 따라 처리를 진행합니다.

이때 처리에 필요한 데이터는 리파지터리가 DB에서 가져와 서비스로 반환합니다.

이렇게 대부분의 웹 서비스는 컨트롤러와 리파지터리 사이에 서비스 계층을 두어서 역할을 분업합니다.

2.트랜잭션

모두 성공해야 하는 일련의 과정으로, 쪼갤 수 없는 업무 처리의 최소 단위입니다. 보통 트랜잭션은 서비스 단에서 관리합니다.

3.롤백

트랜잭션 내부에서 실행에 실패하면 지금까지 수행한 것을 모두 폐기하고 진행 초기 단계로 되돌리는데, 이를 롤백이라고 합니다.

4.@Service

해당 어노테이션이 선언된 클래스를 서비스로 인식해 서비스 객체를 생성합니다. 컨트롤러는 객체 주입(@Autowired를 통해 객체를 가져와 연결)하는 방식으로 서비스 객체를 사용할 수 있습니다.

5.@Transactional

해당 어노테이션이 선언된 메서드를 트랜잭션으로 묶습니다. 클래스에 이 어노테이션을 선언하면 클래스의 모든 메서드별로 각각의 트랜잭션이 부여됩니다.

이렇게 트랜잭션으로 묶인 메서드는 처음부터 끝까지 완전히 실행되거나 아예 실행되지 않거나 둘 중 하나로 동작합니다.

중간에 실패하면 롤백해 처음 상태로 되돌아가기 때문입니다.

12장 수행 결과

image image image image image image image

셀프체크 수행 결과

image image image

13장. 테스트 코드 작성하기

1.테스트

프로그램의 품질을 검증하는 것으로, 의도대로 프로그램이 잘 동작하는지 확인하는 과정입니다.

2.테스트 코드 작성법

테스트 코드는 다음과 같이 3단계로 작성합니다.

  1. 예상 데이터 작성하기

  2. 실제 데이터 획득하기

  3. 예상 데이터와 실제 데이터 비교해 검증하기

3.테스트 케이스

테스트는 다양한 경우를 대비해 작성하는데, 이를 테스트 케이스라고 합니다.

테스트 케이스는 성공할 경우뿐만 아니라 실패할 경우까지 고려해 작성합니다.

더 나아가 성공1, 성공2, …, 실패1, 실패2, …와 같이 다양한 상황을 예상해 세부적으로 작성합니다.

4.test 디렉터리 위치

test 디렉터리는 main 디렉터리 아래에 만들어지는데, 기존 자바 코드가 담긴 main > java 디렉터리와 데칼코마니처럼 test > java 디렉터리로 생성됩니다.

5.@SpringBootTest

스프링 부트와 해당 클래스를 연동해 테스트할 때 사용하는 어노테이션입니다.

테스트 코드에서 스프링 부트가 관리하는 다양한 객체를 주입받을 수 있습니다.

6.@Test

해당 메서드가 테스트를 위한 코드라고 선언하는 어노테이션입니다.

7.테스트 케이스의 트랜잭션 처리

테스트 시 데이터를 조회하는 것이 아닌 조작(생성/수정/삭제)하는 작업을 했다면 테스트를 마치고 데이터를 롤백해야 합니다. 롤백하지 않으면 테스트 수행으로 조작된 데이터가 남아 문제를 일으킬 수 있습니다.

롤백하지 않으면 테스트 수행으로 조작된 데이터가 남아 문제를 일으킬 수 있습니다.

롤백은 테스트 메서드 위에 @Transactional 어노테이션을 붙여 해당 메서드를 트랜잭션 처리해 주면 됩니다.

13장 수행 결과

image image image image image image

셀프체크 수행 결과

image image image image image image image

14장. 댓글 엔티티와 리파지터리 만들기

1.일대다 관계, 다대일 관계

한 엔티티의 하나의 데이터가 다른 엔티티의 여러 데이터와 연관될 때 이를 일대다 관계라고 합니다.

반대로 한 엔티티의 여러 데이터가 다른 엔티티의 한 데이터와 연관될 때는 다대일 관계라고 합니다.

2.대표키와 외래키

엔티티에서 자신을 대표하는 값을 대표키라고 하고, 다른 엔티티를 참조할 수 있도록 다른 엔티티의 대표키를 가리키는 값을 왜래키라고 합니다.

3.다대일 관계 설정

두 엔티티를 다대일 관계로 설정하려면 대표키와 왜리키를 연결해야 합니다.

자식 엔티티의 외래키를 만들어 부모 엔티티의 대표키 값을 갖게 합니다.

4.@ManyToOne

두 엔티티를 다대일 관계로 설정하는 어노테이션입니다.

5.@JoinColumn

해당 엔티티에 외래키를 생성하는 어노테이션입니다.

name 속성으로 매핑할 외래키 이름을 지정할 수 있습니다.

@JoinColumn(name=”외래키_이름”)

6.JpaRepository

ListCrudRepository와 ListPagingAndSortingRepository를 상속받은 인터페이스로, CRUD(생성, 조회, 수정, 삭제) 기능뿐만 아니라 엔티티를 페이지 단위로 조회 및 정렬하는 기능과 JPA에 특화된 여러 기능 등을 제공합니다.

JpaRepository<대상_엔티티, 대표키_값의_타입>

7.네이티브 쿼리 메서드

리파지터리의 메서드로 쿼리를 작성해 실행하는 것을 말합니다.

네이티브 쿼리를 메서드는 @Query 어노테이션이나 orm.xml 파일을 이용해 만들 수 있습니다.

8.@Query

SQL과 유사한 JPQL이라는 객체 지향 쿼리 언어를 통해 쿼리를 처리할 수 있도록 지원하는 어노테이션입니다.

기존의 SQL 문을 그대로 쿼리 언어로 사용하고 싶다면 nativeQuery 속성을 true로 설정하면 됩니다.

@Query(value = “쿼리”, nativeQuery = true)

9.네이티브 쿼리 XML

메서드에서 수행할 쿼리를 XML로 작성한 것을 말합니다.

네이티브 쿼리 XML의 기본 경로와 파일 이름은 META-INF > orm.xml입니다.

이 경로와 이름으로 파일을 만들면 XML이 자동으로 인식됩니다.

10.orm.xml 코드 작성 방법

orm.xml 파일이 생성되면 먼저 엔티티 매핑을 XML 기본 코드를 작성한 후 < entity-mappings > 캐그 안에 < named-native-query >와 < query > 태그를 이용해 쿼리를 입력합니다.

<named-native-query
        name="쿼리_수행_대상_엔티티.메서드_이름"
        result-class="쿼리_수행_결과_반환하는_타입의_전체_패키지_경로">
    <query>
        <![CDATA[
            <!-- 쿼리 -->
        ]]>
    </query>
</named-native-query>

11.@DataJpaTest

JPA와 연동한 테스트를 진행하는 어노테이션입니다.

이를 통해 리파지터리와 엔티티 등의 객체를 테스트 코드에서 사용할 수 있습니다.

12.@DisplayName

테스트 이름을 붙일 때 사용합니다. 기본적으로 테스트 이름은 메서드 이름을 따라가는데, 메서드 이름은 그대로 둔 채 테스트 이름을 바꾸고 싶을 때 이 어노테이션을 사용합니다.

@DisplayName(“테스트_결과에_보여_줄_이름”)

14장 수행 결과

image image image

셀프체크 수행 결과

image image

15장. 댓글 컨트롤러와 서비스 만들기

1.댓글 CRUD를 위한 REST API

댓글 데이터를 CRUD하기 위해서는 REST 컨트롤러, 서비스, DTO, 엔티티, 리파지터리가 필요합니다.

  • REST 컨트롤러: 댓글 REST API를 위한 컨트롤러로 서비스와 협업, 클라이언트 요청을 받아 응답하며 뷰가 아닌 데이터 반환

  • 서비스: REST 컨트롤러와 리파지터리의 사이에서 비즈니스 로직, 즉 처리 흐름을 담당하며 예외 상황이 발생했을 때 @Transactional로 변경된 데이터 롤백

  • DTO: 사용자에게 보여 줄 댓글 정보를 담은 것, 단순히 클라이언트와 서버 간에 댓글 JSON 데이터 전송

  • 엔티티: DB 데이터를 담는 자바 객채로 엔티티를 기반으로 테이블 생성, 리파지터리가 DB 속 데이터를 조회하거나 전달할 때 사용

  • 리파지터리: 엔티티를 관리하는 인터페이스로 데이터 CRUD 등의 기능 제공, 서비스의 명령을 받아 댓글 CRUD 등의 명령을 DB에 보내고 응답받음

2. 댓글 엔티티의 메서드

댓글(Comment) 엔티티에는 2개의 메서드가 있습니다.

하나는 댓글을 생성하는 메서드(createComment())이고, 다른 하나는 댓글을 수정하는 메서드(patch())입니다.

  • 댓글 생성 메서드(createComment()): dto와 article을 입력받아 새 댓글 엔티티를 반환합니다. 정적 메서드이므로 객체 생성 없이 ‘클래스이름.메서드이름(매개변수)’로 호출합니다.

  • 댓글 수정 메서드(patch()): 기존 댓글 엔티티에 입력받은 dto를 반영해 갱신합니다. 비정적 메서드이므로 주제 객체가 있어야만 호출할 수 있습니다.

3. 스트림(stream)

컬렉션이나 리스트에 저장된 요소들을 하나씩 참조하며 반복해서 처리할 때 사용합니다. 스트림을 사용하면 for() 문을 사용하지 않고도 깔끔하고 직관적이게 코드를 변경할 수 있습니다.

스트림의 주요 특징은 다음과 같습니다.

  • 원본 데이터를 읽기만 하고 변경하지 않는다.
  • 정렬된 결과를 컬렉션이나 배열에 담아 반환할 수 있다.
  • 내부 반복문으로, 반복문이 코드상에 노출되지 않는다.

4. @JsonProperty

JSON 데이터의 키와 이를 받아 저장하는 DTO 필드의 변수명이 다를 경우 사용합니다.

DTO 필드 위에 @JsonProperty(“키_이름”)을 작성해 주면 해당 키와 변수가 자동으로 매핑됩니다.

5.orElseThrow()

Optional 객체(존재할 수도 있지만 안 할 수도 있는 객체, 즉 null이 될 수도 있는 객체)에 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 전달값으로 보낸 예외를 발생시키는 메서드입니다.

전달값으로 IllegalArgumentException 클래스를 사용하면 메서드가 잘못됐거나 부적합한 전달값을 보냈음을 나타냅니다.

15장 수행 결과

image image image image

셀프체크 수행 결과

image

REST API 주소

HTTP 메소드 요청 주소 비고
POST /pizzas 피자 등록(JSON 데이터 입력)
GET /pizzas/{id} 피자 단건 조회
GET /pizzas 피자 목록 조회
PATCH /pizzas/{id} 피자 수정(JSON 데이터 입력)
DELETE /pizzas/{id} 피자 삭제

댓글남기기