3. spring data REST ?
- spring data REST 프로젝트는 spring에서 REST 서비스를 빠르게 구성하도록
제공하는 기술.
- 일반적으로, spring data REST는 spring data 프로젝트 위에 구축되어 HAL을
사용하는 하이퍼미디어 유형으로 spring data repository에 연결되는 하이퍼
미디어 기반 REST 서비스를 쉽게 만들수 있게 해주는 기술.
HAL = Hypertext Application Language
-> 요약하면, REST API 또는 RESTful 서비스를 쉽게 만들기 위한 기술.
4. spring data REST ?
-> 기존 방식은, 매우 지루하고, 보편적인 코드를 생성 또는 반복되고 단순
한 코드를 생성
장점 단점
-어떻게 동작하는지 파악(명확함)
-쉬운 디버깅
-간단한 API를 위한 많은 코드가 생김
-코드중복
-비즈니스 로직 없음
5. spring data REST 특징 ?
- repository interface 정의만으로 REST API 구성.
- spring data JPA Query Method 선언으로 API를 구성 및 제공.
- 데이터 표현방식을 다양하게 정의 가능(projection)
- HATEOAS : Hypermedia As The Engine Of Application State
HEATOAS? HAL? 무슨 의미지?
- HATEOAS는 응용 프로그램 아키텍처의 개념입니다. 이는 서버가 리턴 한
자원 모델에서 찾은 하이퍼 미디어 링크를 탐색하여 응용 프로그램 클라이
언트가 서버와 상호 작용하는 방식을 정의합니다. HATEOAS를 구현하려면
다음과 같이 하이퍼 미디어 정보 (관련 리소스에 대한 링크)를 포함하는 리
소스를 나타내는 표준 방법이 필요
- HAL은 API의 리소스들 사이에 쉽고 일관적인 하이퍼링크를 제공하는 방
식이다. API 설계시 HAL을 도입하면 API간에 쉽게 검색이 가능하다. 따라서
해당 API를 사용하는 다른 개발자들에게 좀 더 나은 개발 경험을 제공한다.
즉, HAL을 API Response 메시지에 적용하면 그 메시지가 JSON 포맷이건
XML 포맷이건 API를 쉽게 찾을 수 있는 메타 정보들을 포함시킬 수 있다는
것
참조1 : http://blog.aliencube.org/ko/2015/08/16/applying-hal-to-rest-api/
참조2 : http://blog.woniper.net/219
{
"productId": 1,
"name": "ABC",
"description": "Product ABC",
"unitPrice": 9.99
}
{
"_links": {
"self": {
"href": "/product/1"
},
"collection": {
"href": "/products"
},
"templated": {
"href": "/product/{productId}",
"templated": true
}
},
"productId": 1,
"name": "ABC",
"description": "Product ABC"
"unitPrice": 9.99
}
<일반적인 REST API 의 JSON 응답 메시지>
<REST API 의 HAL이 구현된 JSON 응답 메시지>
6. @RepositoryRestResource
public interface DepartmentRepository extends JpaRepository<Department, Integer> {
@RestResource(path = "department_name")
List<Department> findByDepartmentNameContaining(@Param("departmentName") String departmentName); //전체검색
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = "departmentGroup")
@EqualsAndHashCode(exclude = "departmentGroup")
@Entity
@Table(name = "department")
public class Department {
@Column(name = "department_idx", nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int departmentIdx;
@Column(name = "department_name")
private String departmentName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_group_idx", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
private DepartmentGroup departmentGroup;
}
Repository
Domain
이 2가지만 구현하고, repository에, @RepositoryRestResource 를
붙여주면.. 헐.. 끝났다?!
그런데, 정말 repository interface만으로 동작하는건가?
걱정하지 말아라. 이미 구현체가 만들어져 있다.
7. @RepositoryRestResource
public interface DepartmentRepository extends JpaRepository<Department, Integer> {
@RestResource(path = "department_name")
List<Department> findByDepartmentNameContaining(@Param("departmentName") String departmentName); //전체검색
}
Repository
나는 REST API 입니다. (설정을 했다면, 이런식으로 구성해줘!)
/{entity}s/{id}
exported() : Repository interface를 REST API로 사용할지 여부
path() : URI 매핑 설정 (기본 URI는 entity의 복수)
collectionResourceRel() : HATEOAS collection rel name 설정
collectionresourceDescription() : HATEOAS collection rel 설명 설정
itemresourceRel() : HATEOAS item rel name 설정
itemResourceDescription() : HATEOAS item rel 설명 설정
excerptProjection() : 기본 Projection 설정
8. spring data REST config ?
Spring Boot configurable properties
Name Description
basePath root URI for Spring Data REST
defaultPageSize change default number of items served in a single page
maxPageSize change maximum number of items in a single page
pageParamName change name of the query parameter for selecting pages
limitParamName change name of the query parameter for number of items to show in a page
sortParamName change name of the query parameter for sorting
defaultMediaType change default media type to use when none is specified
returnBodyOnCreate change if a body should be returned on creating a new entity
returnBodyOnUpdate change if a body should be returned on updating an entity
9. spring data REST ?
- repository detection
1. Default
2. Visibility
3. Annotation
4. All
속성 설명
Default public spring 데이터 저장소 또는 @RepositoryRestResource 달린 저장소만 노출
Visibility 오직, public spring 데이터 저장소만 노출
Annotation @RepositoryRestResource 또는 @RestResource로 노출 된 저장소 만 노출, exported =false
로 설정되지 않습니다.
All 주석 또는 엑세스 제어에 관계없이, 모든 Spring Data Repository를 노출
RepositoryDetectionStrategies를 사용하여 REST는 기본 Spring Data JPA 저장소에 대한 액세스를 허용하거나 제한합니다.
옵션은 ALL, Annotated, Visibility 또는 DEFAULT
10. spring data REST ?
- Hiding repository And Method -> exported 속성을 이용
(@RestResource 에도 적용 가능)
11. spring data REST ?
- Repository URI set -> path 속성을 이용
(@RestResource 에도 적용 가능)
12. spring data REST ?
- Repository URI set -> path 속성을 이용
(@RestResource 에도 적용 가능)
만약, @RestResource에 path를 지정하고 저렇게 메소드를 지정하면 어떻게
되나요?
13. spring data REST ?
- 파라미터를 받는 API를 생성하려면?
-> 이름값을 넘겨서 해당하는 사람만 결과를 주세요!
15. spring data REST ?
- HATEOAS 표현이 마음에 안들어. 다른 방법 없을까?
-> Projection 사용!
Projection 은 응답 객체에 포함하려는 필드를 설명하기 위해 선언하는 특수 유형의 계약입
니다. Java의 관점에서, 영사법은 클라이언트에게 보낼 필드를 선언하는 인터페이스입니다.
Spring Data REST는 객체를 직렬화 할 때 요청 된 Projection을 찾고 인터페이스를 사용하여
어떤 필드가 포함되어야 하는지를 결정.
17. spring data REST ?
1 2 3
4
5
5
번호 내용
1. @Projection @Projection 어노테이션은 해당 인터페이스가 projection이라고 표시.
2. @Projection(name=“”) name속성은 projection의 이름을 제공
3. @Projection(types=“”) types속성은 해당 projection을 Department 클래스의 객체에만 적용하도록 대상을 지정.
4. Public interface DepartmentPojectionInterface {} 이 부분은 선언적으로 만드는 Java 인터페이스.
5. Int getDepartmentIdx();
6. DepartmentGroup getDepartmentGroup();
departmentIdx, departmentGroup의 정보를 노출합니다.
Spring data rest는 어떻게 투영정보를 찾을까?
Entity 정의와 같은 패키지에 인터페이스 등록
또는 하위패키지
21. spring data REST 마치며.
- spring data rest에 대해서, 간편하게 살펴 보았습니다.
- 빠르게 만들수 있게 제공되는 다양한 기능들이 존재.
- 빠르게 만들수 있으나, REST 및 ORM(JPA)에 대한 선행학습 필요.
코드 : https://github.com/phpbae/springBootDataRest