코딩 요정 버터링

Spring Boot2 webflux 방식으로 CRUD 예제를 만들어보자(1) 본문

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 처리까지 완벽!

신세계를 맛본듯하다.   

Comments