Skip to content

Assembler v0.7.6

Compare
Choose a tag to compare
@pellse pellse released this 21 Oct 23:44
· 59 commits to main since this release

What's Changed

  • The use of embedded Assembler instances allows for the aggregation of sub-queries defined in rules. This new feature was heavily inspired by this great article from Vlad Mihalcea. It enables the modeling of a complex relationship graph (or, as mentioned in the article, a multi-level hierarchical structure) of disparate data sources (e.g., microservices, relational or non-relational databases, message queues, etc.) without triggering either N+1 queries or a Cartesian product.

    See EmbeddedAssemblerTest.java for an example of how to use this new feature:

Assembler<UserVoteView, UserVote> userVoteAssembler = assemblerOf(UserVote.class)
    .withCorrelationIdResolver(UserVoteView::id)
    .withRules(
        rule(User::id, UserVoteView::userId, oneToOne(call(this::getUsersById))),
        UserVote::new
    )
    .build();

Assembler<PostComment, PostComment> postCommentAssembler = assemblerOf(PostComment.class)
    .withCorrelationIdResolver(PostComment::id)
    .withRules(
        rule(UserVote::commentId, oneToMany(UserVote::id, call(assemble(this::getUserVoteViewsById, userVoteAssembler)))),
        PostComment::new
    )
    .build();

Assembler<PostDetails, Post> postAssembler = assemblerOf(Post.class)
    .withCorrelationIdResolver(PostDetails::id)
    .withRules(
        rule(PostComment::postId, oneToMany(PostComment::id, call(assemble(this::getPostCommentsById, postCommentAssembler)))),
        rule(PostTag::postId, oneToMany(PostTag::id, call(this::getPostTagsById))),
        Post::new
    )
    .build();

// If getPostDetails() is a finite sequence
Flux<Post> posts = postAssembler.assemble(getPostDetails());

// If getPostDetails() is a continuous stream
Flux<Post> posts = getPostDetails()
    .windowTimeout(100, Duration.ofSeconds(5))
    .flatMapSequential(postAssembler::assemble);
  • Big improvement in concurrency management, better fairness introduced in reactive read-write lock implementation
  • Support for configuration of Scheduler backed by virtual thread executor
    • By default, AssemblerBuilder will use Schedulers.boundedScheduler() if reactor.schedulers.defaultBoundedElasticOnVirtualThreads system property is present