카테고리 없음

태태개발일지 - WebFlux

태태코 2024. 5. 27. 20:48
반응형

- WebFlux

리액티브 프로그래밍은 비동기 및 이벤트 기반 애플리케이션을 개발하기 위한 패러다임으로, 주로 높은 확장성과 성능을 위해 사용됩니다

 

비동기 프로그램으로 MVC 방식과 성능 비교를 했을 때 확연하게 빨라지는 것을 JMeter를 통해 검증 완료했다.

 

하나를 반환할때는 Mono , 여러개 반환하려면 Flux를 반환하게 된다.

 

Spring MVC와 방식은 비슷하고.

public interface PostR2dbcRepository extends ReactiveCrudRepository<Post, Long>, PostCustomR2dbcRepository{
    Flux<Post> findByUserId(Long id);
}

 

Repostiory는 ReactiveCrudRepository를 상속하게 된다.

   @GetMapping("/{id}")
    public Mono<PostResponse> getPostContent(@PathVariable Long id) {
        return postService.getPostContent(id);
    }
    
     @GetMapping("")
    public Flux<PostResponseV2> findAllPost() {
        return postServiceV2.findAll()
                .map(PostResponseV2::of);
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<PostResponseV2>> findPost(@PathVariable Long id) {
        return postServiceV2.findById(id)
                .map(p -> ResponseEntity.ok().body(PostResponseV2.of(p)))
                .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
    }

 

Controller는 다음과 같은 방식으로 사용한다.

 

 public Mono<Post> create(Long userId, String title, String content) {
        return postR2dbcRepository.save(Post.builder()
                .userId(userId)
                .title(title)
                .content(content)
                .build());
    }

    public Flux<Post> findAll() {
        return postR2dbcRepository.findAll();
    }

service는 다음과 같이 사용하고,

 

만약 연관관계 없이 데이터를 처리해서 보내주려면

@Repository
@RequiredArgsConstructor
public class PostCustomR2dbcRepositoryImpl implements PostCustomR2dbcRepository {
    private final DatabaseClient databaseClient;

    @Override
    public Flux<Post> findAllByUserId(Long userId) {
        var sql = """
                SELECT p.id as pid, p.user_id as userId, p.title, p.content, p.created_at as createdAt, p.updated_at as updatedAt,
                    u.id as uid, u.name as name, u.email as email, u.created_at as uCreatedAt, u.updated_at as uUpdatedAt
                FROM posts p
                LEFT JOIN users u ON p.user_id = u.id
                WHERE p.user_id = :userId
                """;
        return databaseClient.sql(sql)
                .bind("userId", userId)
                .fetch()
                .all()
                .map(row -> Post.builder()
                        .id((Long) row.get("pid"))
                        .userId((Long) row.get("userId"))
                        .title((String) row.get("title"))
                        .content((String) row.get("content"))
                        .user(User.builder()
                                .id((Long)row.get("uid"))
                                .name((String)row.get("name"))
                                .email((String)row.get("email"))
                                .createdAt(((ZonedDateTime)row.get("uCreatedAt")).toLocalDateTime())
                                .createdAt(((ZonedDateTime)row.get("uUpdatedAt")).toLocalDateTime())
                                .build()
                        )
                        .createdAt(((ZonedDateTime)row.get("createdAt")).toLocalDateTime())
                        .createdAt(((ZonedDateTime)row.get("updatedAt")).toLocalDateTime())
                        .build());
    }
}

databaseclint 사용하여  쿼리를 통해 매핑하여 해결한다.

 

 

결론: 

아직 몇시간 만 공부해서 어떤 상황에서 써야 MVC보다 효율적이고 두개를 같이 병행하여 사용할 수 있는 건지 다양한 궁금증 을 해결해 나갈 생각이다.

반응형