1. 개요 

 
이 기사에서는 SpringData REST의  Projections 과 Excerpts 개념을 살펴볼 것입니다.우리는 방법을 학습합니다

우리의 모델의 사용자 정의보기를 생성하는 예측을 사용하여 자원 콜렉션에 대한 기본보기로 Excerpts을 사용하는 방법

.

2. 우리의 도메인 모델

 
먼저 도메인 모델 인

Book

Author 를 정의하여 시작하겠습니다 

.

Book

 엔티티 클래스를 살펴 보겠습니다  .
@Entity
public class Book {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String title;
    
    private String isbn;

    @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER)
    private List<Author> authors;
}
그리고 

저자

모델 :
@Entity
public class Author {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String name;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
      name = "book_author", 
      joinColumns = @JoinColumn(
        name = "book_id", referencedColumnName = "id"), 
      inverseJoinColumns = @JoinColumn(
        name = "author_id", referencedColumnName = "id"))
    private List<Book> books;
}
두 엔터티는 다 대다 관계도 있습니다.다음으로 각 모델에 대한 표준 SpringData REST 저장소를 정의 해 보겠습니다.
public interface BookRepository extends CrudRepository<Book, Long> {}
public interface AuthorRepository extends CrudRepository<Author, Long> {}
이제

Book

엔드 포인트에 액세스 하여 http : // localhost : 8080 / books / {id} 에서 ID를 사용하여 특정

도서의

세부 정보 를 가져올 수 있습니다

.

{
  "title" : "Animal Farm",
  "isbn" : "978-1943138425",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1"
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}
이후합니다 

저자

모델의 저장소를 가지고, 저자의 세부 사항은 응답의 일부가 아닙니다. 그러나 http : // localhost : 8080 / books / 1 / authors에 대한 링크를 찾을 수 있습니다 

.

3. Projections 만들기

 
때로는

항목 속성의 하위 집합 또는 사용자 지정보기에만 관심이

있습니다. 이러한 경우에는 Projections을 사용할 수 있습니다.SpringData REST 프로젝션을 사용하여

Book에

대한 사용자 정의 뷰를 생성 해 보겠습니다 .CustomBook  이라는  간단한

프로젝션

을 만드는 것으로 시작하겠습니다 .
@Projection(
  name = "customBook", 
  types = { Book.class }) 
public interface CustomBook { 
    String getTitle();
}
참고

우리의 돌출부가와 인터페이스로 정의된다 @Projection의 주석

.

name

속성을 사용하여 프로젝션의 이름을 사용자 정의하고

유형

 속성을 사용하여 적용되는 객체를 정의 할 수 있습니다.이 예에서

CustomBook

프로젝션은

제목

만 포함합니다 .Projections 을 만든 후

표현을 다시 살펴 보겠습니다

.

{
  "title" : "Animal Farm",
  "isbn" : "978-1943138425",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}
좋습니다. Projections에 대한 링크를 볼 수 있습니다.

http : // localhost : 8080 / books / 1? projection = customBook

에서 생성 한 뷰를 확인해 보겠습니다 .
{
  "title" : "Animal Farm",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}
여기서는

제목

필드 만 가져

오고 isbn

은 더 이상 사용자 정의보기에 표시되지 않음을 알 수 있습니다.일반적으로 http : // localhost : 8080 / books / 1? projection = {projection name} 에서 Projections 결과에 액세스 할 수 있습니다 

.

또한 모델과 동일한 패키지에

Projection

을 정의해야합니다 . 또는

RepositoryRestConfigurerAdapter

사용 하여 명시 적으로 추가 할 수 있습니다 .
@Configuration
public class RestConfig implements RepositoryRestConfigurer {
 
    @Override
    public void configureRepositoryRestConfiguration(
      RepositoryRestConfiguration repositoryRestConfiguration) {
        repositoryRestConfiguration.getProjectionConfiguration()
          .addProjection(CustomBook.class);
    }
}

4. Projections에 새 데이터 추가

 
이제 프로젝션에 새 데이터를 추가하는 방법을 살펴 보겠습니다.이전 섹션에서 논의했듯이 Projections을 사용하여 뷰에 포함 할 속성을 선택할 수 있습니다. 또한 원래보기에 포함되지 않은 데이터를 추가 할 수도 있습니다.

4.1. 숨겨진 데이터

 
기본적으로 ID는 원래 리소스보기에 포함되지 않습니다.결과에서

id를보기

위해 id 필드를 명시 적으로 포함 할 수 있습니다 .
@Projection(
  name = "customBook", 
  types = { Book.class }) 
public interface CustomBook {
    @Value("#{target.id}")
    long getId(); 
    
    String getTitle();
}
이제 

http : // localhost : 8080 / books / 1? projection = {projection name}의 출력 

은 다음과 같습니다.
{
  "id" : 1,
  "title" : "Animal Farm",
  "_links" : {
     ...
  }
}
@JsonIgnore 를 사용하여 원래보기에서 숨겨진 데이터를 포함 할 수도 있습니다 

.

4.2. 계산 된 데이터

 
리소스 속성에서 계산 된 새 데이터를 포함 할 수도 있습니다.예를 들어 Projection에 작성자 수를 포함 할 수 있습니다.
@Projection(name = "customBook", types = { Book.class }) 
public interface CustomBook {
 
    @Value("#{target.id}")
    long getId(); 
    
    String getTitle();
        
    @Value("#{target.getAuthors().size()}")
    int getAuthorCount();
}
그리고 우리는 그것을 확인할 수 있습니다 

에 http : // localhost를 : 8080 / 책 / 1 프로젝션 = customBook를

:
{
  "id" : 1,
  "title" : "Animal Farm",
  "authorCount" : 1,
  "_links" : {
     ...
  }
}

4.3. 관련 리소스에 쉽게 액세스

마지막으로, 책의 저자와 같이 일반적으로 관련 리소스에 액세스해야하는 경우 명시 적으로 포함하여 추가 요청을 피할 수 있습니다.
@Projection(
  name = "customBook", 
  types = { Book.class }) 
public interface CustomBook {
 
    @Value("#{target.id}")
    long getId(); 
    
    String getTitle();
    
    List<Author> getAuthors();
    
    @Value("#{target.getAuthors().size()}")
    int getAuthorCount();
}
그리고 최종

Projection

출력은 다음과 같습니다.
{
  "id" : 1,
  "title" : "Animal Farm",
  "authors" : [ {
    "name" : "George Orwell"
  } ],
  "authorCount" : 1,
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/books/1"
    },
    "book" : {
      "href" : "http://localhost:8080/books/1{?projection}",
      "templated" : true
    },
    "authors" : {
      "href" : "http://localhost:8080/books/1/authors"
    }
  }
}
다음으로 Excerpts 부분을 살펴 보겠습니다.

5. Excerpts

 

Excerpts는 리소스 컬렉션에 대한 기본보기로 적용되는 예측입니다.

컬렉션 응답에 대해 customBook Projection을 자동으로 사용하도록

BookRepository

를  사용자 지정해 보겠습니다 .

 

이를 위해 @RepositoryRestResource 주석

excerptProjection

속성을 사용합니다 .
@RepositoryRestResource(excerptProjection = CustomBook.class)
public interface BookRepository extends CrudRepository<Book, Long> {}
이제 http : // localhost : 8080 / books 를 호출하여

customBook

이 도서 컬렉션의 기본보기 인지 확인할 수 있습니다  .
{
  "_embedded" : {
    "books" : [ {
      "id" : 1,
      "title" : "Animal Farm",
      "authors" : [ {
        "name" : "George Orwell"
      } ],
      "authorCount" : 1,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/books/1"
        },
        "book" : {
          "href" : "http://localhost:8080/books/1{?projection}",
          "templated" : true
        },
        "authors" : {
          "href" : "http://localhost:8080/books/1/authors"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/books"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/books"
    }
  }
}

http : // localhost : 8080 / authors / 1 / books

에서 특정 저자의 책을 보는 경우에도 동일하게 적용됩니다  .
{
  "_embedded" : {
    "books" : [ {
      "id" : 1,
      "authors" : [ {
        "name" : "George Orwell"
      } ],
      "authorCount" : 1,
      "title" : "Animal Farm",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/books/1"
        },
        "book" : {
          "href" : "http://localhost:8080/books/1{?projection}",
          "templated" : true
        },
        "authors" : {
          "href" : "http://localhost:8080/books/1/authors"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/authors/1/books"
    }
  }
}
언급했듯이 Excerpts는 컬렉션 리소스에만 자동으로 적용됩니다. 단일 리소스의 경우 이전 섹션에 표시된

프로젝션

매개 변수 를 사용해야합니다 .단일 리소스에 대한 기본보기로 Projections을 적용하면 부분보기에서 리소스를 업데이트하는 방법을 알기가 어렵 기 때문입니다.마지막으로,

Projections과 Excerpts는 읽기 전용이라는 것을

기억하는 것이 중요합니다 .

6. 결론

 
SpringData REST 프로젝션을 사용하여 모델의 사용자 지정 뷰를 만드는 방법을 배웠습니다. 또한 리소스 컬렉션에 대한 기본보기로 Excerpts를 사용하는 방법도 배웠습니다.예제의 전체 소스 코드는

GitHub

에서 찾을 수 있습니다 .