spring boot
Spring Boot2 webflux 방식으로 CRUD 예제를 만들어보자(1)
butter-ring
2019. 7. 1. 17:59
취업을 하면서 Spring boot2 를 사용하여 RESTful Api를 사용하게 되었다.
JPA repository를 이용하여 CRUD 를 만들어 볼텐데
기본적인 CRUD 중 오늘은 R.. read를 작성해보도록 한다.
일단 공통으로 쓰는 BaseEntity를 작성한다.
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Data
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int active = 1;
private Long createdAt = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
private Long updatedAt = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
}
그리고 사용 할 Sample을 만들고 BaseEntity를 상속받는다.
import com.exchange.admin.api.common.model.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Entity
public class Sample extends BaseEntity {
private String title;
@Column(columnDefinition = "LONGTEXT", nullable = false)
private String content;
}
SampleRepository를 작성하고 CrudRepository를 상속받는다.
CrudRepository는 JpaRepository의 하위에 속한다.
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface SampleRepository extends CrudRepository<Sample, Long> {
Page<Sample> findAll(Pageable pageable);
}
Jpa의 Page를 사용하면 기본적으로 페이징과 정렬을 해준다. 완전 편하다 최고
mvc 의 controller에 대응되는 handler이다.
첫 페이지는 0번 인덱스(page), 한 페이지에 보여줄 리스트는 20개(pagesize), 정렬은 생성시기 내림차순으로해주고(sort)
모노객체에 담아서 리턴 데이터가 없을시 notFound를 리턴한다.
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.ServerResponse.notFound;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@Slf4j
@Component
public class SampleHandler {
private final SampleRepository sampleRepository;
public SampleHandler(SampleRepository sampleRepository) {
this.sampleRepository=sampleRepository;
}
/**
* GET Samples
*/
// @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_USER')")
public Mono<ServerResponse> findAll(ServerRequest request) {
log.info("]-----] SampleHandler::findAll call [-----[ ");
Integer page = request.queryParam("page").isPresent() ? Integer.parseInt(request.queryParam("page").get()) - 1 : 0;
Integer size = request.queryParam("pagesize").isPresent() ? Integer.parseInt(request.queryParam("pagesize").get()) : 20;
Sort sort = new Sort(Sort.Direction.DESC, "createdAt");
return Mono.just(sampleRepository.findAll(PageRequest.of(page, size, sort)))
.flatMap(sample -> ok().body(fromObject(sample)))
.switchIfEmpty(notFound().build());
}
}
핸들러까지 잘 작성했다면 SampleRouter를 작성해보자
요청을 handler로 routing해주는 routerFunction이다.
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
@Slf4j
@Configuration
public class SampleRouter {
@Bean
public RouterFunction<ServerResponse> sampleRouterFunction(SampleHandler handler) {
return RouterFunctions
.nest(path("/api/sample"),
route(GET("").and(accept(APPLICATION_JSON_UTF8)), handler::findAll)
);
}
}
여기선 데이터 형식을 어떤 형식으로 보내고 받을지 GET 방식인지 POST 방식인지 요청 URL은 무엇인지
그런것들을 설정하여준다.
이제 서버를 돌리고 포스트맨으로 요청하여 응답이 잘 오는지 확인해보자
GET방식으로 요청하였고 데이터를 잘 받아온다. Pagination 처리까지 완벽!
신세계를 맛본듯하다.