티스토리 뷰
안녕하세요 강정호입니다.
오늘은 Spring Data REST 복습을 해보려고 합니다.
Spring Data REST의 깃헙 프로젝트
https://github.com/spring-projects/spring-data-rest
[Spring Data REST란 무엇인가?]
Spring Data REST를 이해하기 위해서는 먼저 RESTful한 웹서비스가 무엇인지 알아야합니다.
RESTful 웹서비스 : HTTP 메서드를 통해서 해당 자원에 대한 CRUD 수행할 수 있는 서비스를 말한다.
그럼 기존의 RESTful 서비스와 Spring Data REST는 뭐가 더 좋은것인가?
기존에는 @RestController 어노테이션을 사용해서 컨트롤러에서 JSON 형식으로 데이터를 반환해주었습니다.
그리고 이 때 API를 RESTful하게 직접 지정을 해줘야 했습니다.
하지만!! Spring Data REST를 사용하면 별도의 컨트롤러 없이 Entity, Repository 인터페이스를 보고 자동으로 RESTful API를 제공해줍니다. 결국 알아서 생성해준다는게 편하닷!!!
[Spring Data REST를 사용하려면?]
Spring Data REST를 사용하기 위해서는 Entity와 Respository 설정이 필요하다.
Entity 예제
package com.marathon.board.domain;
import java.time.LocalDateTime;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter
@ToString
@Table(indexes = {
@Index(columnList="title"),
@Index(columnList="hashtag"),
@Index(columnList="createdAt"),
@Index(columnList="createdBy")
})
@Entity
public class Article extends AuditingFields {
//본문 인덱스 : 본문검색에는 인덱스를 걸지 않는다. 너무 길어서 본문에는 인덱스 X. 그리고 인덱스에 용량이 한계가 있다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Setter
@Column(nullable = false)
private String title; // 제목
@Setter
@Column(nullable = false, length = 10000)
private String content; // 본문
@Setter
private String hashTag; // 해시태그
@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
private final Set<ArticleComment> articleComments = new LinkedHashSet<>();
protected Article (){
}
private Article(String title, String content, String hashTag) {
this.title = title;
this.content = content;
this.hashTag = hashTag;
}
public static Article of(String title, String content, String hashTag) {
return new Article(title, content, hashTag);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Article article)) {
return false;
}
return id != null && id.equals(article.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
Respository 예제
package com.marathon.board.repository;
import com.marathon.board.domain.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface ArticleRepository extends
JpaRepository<Article, Long> ,
QuerydslPredicateExecutor<Article>
//QuerydslBinderCustomizer<QArticle>
{
}
위와 같이 @RespositoryRestResource 어노테이션을 붙여줘야 Spring Data REST 프레임워크에서 읽어서 API를 엔티티에 맞게 자동으로 생성해준다.
@DisplayName("Data REST 테스트")
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
//@WebMvcTest 미사용 이유 확인하기.
public class DataRestTest {
// WebMvc 테스트는 내부적으로 MockMvc를 사용할 수 있게 해준다.
private final MockMvc mvc;
public DataRestTest(@Autowired MockMvc mvc) {
this.mvc = mvc;
}
@DisplayName("[api] 게시글 리스트 조회")
@Test
void givenNotion_whenRequestArticles_thenReturnArticlesJsonResponse() throws Exception {
//Given
//When & Then
// 단축키1 : 컨트롤 + 스페이스 : MockBuilderGet 사용
// 단축키2: 옵션 + 스페이스 => 항상 스태틱으로 가져오기
mvc.perform(get("/api/articles"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.valueOf("application/hal+json")))
.andDo(print());
/**
* 테스트 실패 이유
* WebMvcTest는 슬라이스 테스트이다.
* 컨트롤러 이외의 빈은 로드하지 않는다. 붎필요하다고 생각하는 빈은 생성하지 않는다
* DataRest의 AutoConfiguration을 읽지 않는다
* 그래서 가장 간단한 방법으로는 이 테스트를 IntegrationTest로 하는 것이다.
* */
}
@DisplayName("[api] 게시글 단건 조회")
@Test
void givenArticleId_whenRequestArticles_thenReturnArticlesJsonResponse() throws Exception {
//Given
//When & Then
// 단축키1 : 컨트롤 + 스페이스 : MockBuilderGet 사용
// 단축키2: 옵션 + 스페이스 => 항상 스태틱으로 가져오기
mvc.perform(get("/api/articles/1"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.valueOf("application/hal+json")))
.andDo(print());
}
@DisplayName("[api] 게시글 댓글 조회")
@Test
void givenArticleId_whenRequestArticleComments_thenReturnArticlesCommentJsonResponse() throws Exception {
//Given
//When & Then
// 단축키1 : 컨트롤 + 스페이스 : MockBuilderGet 사용
// 단축키2: 옵션 + 스페이스 => 항상 스태틱으로 가져오기
mvc.perform(get("/api/articles/1/articleComments"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.valueOf("application/hal+json")))
.andDo(print());
}
@DisplayName("[api] 댓글 리스트 조회")
@Test
void givenNothing_whenRequestArticleComments_thenReturnArticlesCommentJsonResponse() throws Exception {
//Given
//When & Then
// 단축키1 : 컨트롤 + 스페이스 : MockBuilderGet 사용
// 단축키2: 옵션 + 스페이스 => 항상 스태틱으로 가져오기
mvc.perform(get("/api/articleComments"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.valueOf("application/hal+json")))
.andDo(print());
}
@DisplayName("[api] 댓글 단건 조회")
@Test
void givenNothing_whenRequestArticleComment_thenReturnArticleCommentJsonResponse() throws Exception {
//Given
//When & Then
// 단축키1 : 컨트롤 + 스페이스 : MockBuilderGet 사용
// 단축키2: 옵션 + 스페이스 => 항상 스태틱으로 가져오기
mvc.perform(get("/api/articleComments/1"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.valueOf("application/hal+json")))
.andDo(print());
}
}
@Transactional 어노테이션
'Back-end' 카테고리의 다른 글
09. 게시글 페이지 만들기 (0) | 2023.04.05 |
---|---|
[게시판 플젝] Querydsl 의존성 추가 및 api 검색 옵션 추가 (0) | 2023.04.01 |
[JPA] @MappedSuperclass, @EntityListners (0) | 2023.03.25 |
작성해야할 개발 기술 (0) | 2021.01.11 |
[리눅스] 파일 속성 (0) | 2020.04.27 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 인셉션
- 항해솔직후기
- Spring boot
- docker
- 깃
- 도커
- 항해플러스백엔드
- 개발자 회고
- github
- 항해플러스후기
- 부동산공부
- 관계대수
- 재테크공부
- 월급쟁이부자들
- push_back
- 월부닷컴
- front
- 폭포수
- 2023년
- GIT
- Use case
- pop_back
- Inception
- 열반스쿨기초반
- 파라메터
- ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- 내년은 빡세게!!
- resize
- 유즈케이스
- 깃허브
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
글 보관함