반응형
- 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보다 효율적이고 두개를 같이 병행하여 사용할 수 있는 건지 다양한 궁금증 을 해결해 나갈 생각이다.
반응형