스프링 Data Jpa로 API 만들기
2024. 3. 16. 23:33ㆍBackend 취업준비/Spring
스프링이 HTTP응답을 처리하는 방식 3가지가 있었다
- 정적 컨텐츠
- MVC와 템플릿 엔진 (동적 컨텐츠, 타임 리프)
- API
세가지 방식이 있는 것을 알겠는데, 개발자는 어떤 때에 어떤 방식을 선택해서 개발을 해나가야 할까?
기본서에서 글 작성, 글 목록 조회, 글 단건 조회, 글 삭제, 수정 등 여러 API를 만들었었다
하지만 정작 블로그를 구현할 때는 타임리프를 사용해서 뷰와 함께 구현하거나, 삭제 기능 같은 경우는 자바스크립트 만을 사용하여 기능 구현을 하였다
- 타임리프(Thymeleaf):
- 서버 측 렌더링(Server-side Rendering)이 필요한 경우: 사용자에게 동적인 HTML 콘텐츠를 제공해야 하는 경우, 타임리프를 사용하여 서버 측에서 HTML을 동적으로 생성.
- 서버 측에서 모델(Model) 데이터를 HTML에 바인딩하는 경우: 서버 측에서 전달되는 데이터를 HTML 템플릿에 삽입하여 클라이언트에게 제공해야 할 때 유용.
- REST API:
- 클라이언트랑 서버의 완전분리 (웹, 모바일앱등 여러가지에서 하나의 API를 사용해야할떄),
- 클라이언트랑 서버의 완전분리 => 클라이언트-서버 간에 데이터를 주고받아야 하는 경우: 클라이언트 애플리케이션과 서버 간에 데이터를 교환할 때 REST API를 사용. 이는 주로 AJAX 호출을 통해 이루어지며, JSON 또는 XML 형식으로 데이터를 전송.
- 비동기적으로 데이터를 업데이트하거나 가져와야 하는 경우: 웹 애플리케이션에서 페이지 새로고침 없이 데이터를 업데이트하거나 가져와야 할 때 REST API를 활용
- 동적인 UX제공시 (페이지 일부분만의 업데이트가 제공되어야할때)
- 자바스크립트(Javascript):
- 비동기데이터 처리 필요시 (동적 웹 구성)
- 프론트엔드 상태관리(컴포넌트 기반 개발과 상태관리 로직 구현, UI업데이트시 유리)
API방식 ( 스프링 Data JPA를 사용 )
먼저 API란?
- API : 유저랑 서버가 데이터를 주고 받기 위한 방법(결국 코드)
JPA를 사용하려면?
- JPA를 사용하려면 Entity가 필요함
- Entity 객체에는 기본생성자가 꼭 필요하다
- 위 사진에서는 생성자에 빌더 어노테이션을 사용하였으므로 기본 생성자가 자동으로 생성되지 않아 오류가 남
- @NoArgsConstructor를 사용하거나 직접 기본 생성자를 선언해 줘야 한다
- 기본 생성자가 꼭 필요한 이유
- 리플랙션 & 프록시..
@Builder => 클래스 위에 선언, 생성자 위에 선언
클래스 위에 선언
- 클래스 레벨에 @Builder를 선언하면 해당 클래스의 모든 필드에 대한 빌더 메서드가 생성된다.
- 이는 모든 필드에 대해 빌더를 사용하고자 할 때 유용하다.
- 그러나 객체 생성 시 받지 않아야 할 매개변수들도 빌더에 노출될 수 있다
생성자 위에 선언
- 생성자 레벨에 @Builder를 선언하면 해당 생성자만을 위한 빌더 메서드가 생성.
- 해당 생성자로 초기화 되는 필드들에 대해서만 빌더 메서드가 생성.
- 이는 특정 생성자에만 빌더 패턴을 적용하고 싶을 때 유용.
스프링 Data JPA를 사용하려면 JpaRepository 인터페이스를 상속
- JpaRepository 인터페이스를 상속하면 Spring Data JPA는 자동으로 Repository 구현체를 생성하고 빈으로 등록해 준다. => 역시 프록시 개념이 나온다.. 언젠가는 꼭 공부해야 할 것 같다
- EntityManager를 관리해 줄 필요 없다
- @Repository어노테이션을 사용할 필요 없다
- 이를 통해 개발자는 구현체를 직접 작성할 필요가 없고, 인터페이스만을 작성하여 데이터베이스에 대한 기본 CRUD(Create, Read, Update, Delete) 기능을 제공받을 수 있다.
- @NoRepositoryBean 어노테이션은 Spring Data JPA가 해당 인터페이스를 기반으로 자동으로 Repository 구현체를 생성하지 않도록 막는 역할을 한다.
- 이 어노테이션이 붙은 인터페이스는 스프링 데이터의 기본적인 기능을 상속받는 용도로만 사용되며, 직접적으로 스프링 데이터의 구현체가 될 수 없다.
@ResponseBody
- 컨트롤러 메서드가 HTTP 응답의 본문(body)으로 직접 데이터를 반환할 때 사용
- HTTP 규격에 맞는 응답을 만들어주기 위한 Annotation
- ViewResolver 대신에 HttpMessageConverter 가 동작. HTTPMessageConverter 는 해당 Annotation 이 붙은 대상을 response body 에 직렬화를 하는 방식으로 작동
ResponseEntity
- HTTP 응답을 만들어주기 위한 객체.
- @ResponseBody 와 달리 Annotation 이 아닌 객체로 사용. 즉, 응답으로 변환될 정보를 모두 담은 요소들을 객체로 만들어서 반환해 준다.
- HTTP 상태 코드 설정: ResponseEntity.status(HttpStatus status) 메서드를 사용하여 HTTP 응답의 상태 코드를 설정할 수 있다. 예를 들어, ResponseEntity.ok()는 HTTP 상태 코드 200(OK)를 설정
- 헤더 설정: ResponseEntity.headers(HttpHeaders headers) 메서드를 사용하여 HTTP 응답의 헤더를 설정할 수 있다. 이를 통해 응답에 추가적인 정보를 포함할 수 있다.
- 본문 설정: ResponseEntity.body(T body) 메서드를 사용하여 HTTP 응답의 본문을 설정할 수 있다. 이를 통해 클라이언트에게 데이터를 반환. 본문은 제네릭 타입 T로 지정되며, 반환될 데이터의 타입에 따라 적절한 타입을 지정
스프링 데이터 JPA에서 쿼리 날리기
메소드 규칙
- 기본적인 기능 save, delete, findAll, findById 외에도 메서드 명명 규칙을 지킨다면 자동으로 쿼리문을 날려준다
- https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html
@Query
- @Query 어노테이션은 Spring Data JPA에서 메소드 상단에 사용된다.
- JPQL을 사용하여 자동 생성되는 쿼리 메소드 외의 데이터 베이스 쿼리를 직접 정의할 때 사용된다.
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("select p from Post p join fetch p.comments")
List<Post> findAllInnerFetchJoin();
@Query("select distinct p from Post p join fetch p.comments")
List<Post> findAllInnerFetchJoinWithDistinct();
//...
}
- 간단한 로직을 작성하는데 큰 문제는 없으나, 복잡한 로직의 경우 개행이 포함된 쿼리 문자열이 상당히 길어진다.
- JPQL 문자열에 오타 혹은 문법적인 오류가 존재하는 경우, 정적 쿼리라면 어플리케이션 로딩 시점에 이를 발견할 수 있으나 그 외는 런타임 시점에서 에러가 발생한다.
이러한 문제를 어느 정도 해소하는데 기여하는 프레임워크가 바로 QueryDSL
QueryDSL은 정적 타입을 이용해서 SQL 등의 쿼리를 생성해주는 프레임워크
QueryDSL의 장점
- 문자가 아닌 코드로 쿼리를 작성함으로써, 컴파일 시점에 문법 오류를 쉽게 확인할 수 있다.
- 자동 완성 등 IDE의 도움을 받을 수 있다.
- 동적인 쿼리 작성이 편리하다.
- 쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용할 수 있다.
자세한 예시
https://tecoble.techcourse.co.kr/post/2021-08-08-basic-querydsl/
'Backend 취업준비 > Spring' 카테고리의 다른 글
Servlet Filter, Spring Intercepter (0) | 2024.03.19 |
---|---|
@ResponseBody, @ModelAttribute, Model 인터페이스 (2) | 2024.03.18 |
HTTP응답을 처리하는 방식 (@Controller, @RestController) (0) | 2024.03.09 |
JDBC 흐름 정리 (0) | 2024.03.08 |
스프링 빈 (0) | 2024.03.03 |