Skip to content

Assembler v0.7.5

Latest
Compare
Choose a tag to compare
@pellse pellse released this 02 Jul 03:33
· 36 commits to main since this release
4f5c87e

What's Changed

This release fixes an issue where there is no direct correlation ID between a top-level entity and a sub-level entity by introducing the concept of an ID join.

For example, before this release, there was no way to express the relationship between e.g. a PostDetails and a User because User doesn't have a postId field like Reply does, as described in #33.

record PostDetails(Long id, Long userId, String content) {
}

record User(Long Id, String username) { // No correlation Id back to PostDetails
}

record Reply(Long id, Long postId, Long userId, String content) {
}

record Post(PostDetails post, User author, List<Reply> replies) {
}

Assembler<PostDetails, Post> assembler = assemblerOf(Post.class)
    .withCorrelationIdResolver(PostDetails::id)
    .withRules(
        rule(XXXXX, oneToOne(call(PostDetails::userId, this::getUsersById))), // What should XXXXX be?
        rule(Reply::postId, oneToMany(Reply::id, call(this::getRepliesById))),
        Post::new)
    .build();

Since 0.7.5, this relationship can now be expressed:

Assembler<PostDetails, Post> assembler = assemblerOf(Post.class)
    .withCorrelationIdResolver(PostDetails::id)
    .withRules(
        rule(User::Id, PostDetails::userId, oneToOne(call(this::getUsersById))), // ID Join
        rule(Reply::postId, oneToMany(Reply::id, call(this::getRepliesById))),
        Post::new)
    .build();

This would be semantically equivalent to the following SQL query if all entities were stored in the same relational database:

SELECT 
    p.id AS post_id,
    p.userId AS post_userId,
    p.content AS post_content,
    u.id AS author_id,
    u.username AS author_username,
    r.id AS reply_id,
    r.postId AS reply_postId,
    r.userId AS reply_userId,
    r.content AS reply_content
FROM 
    PostDetails p
JOIN 
    User u ON p.userId = u.id -- rule(User::Id, PostDetails::userId, ...)
LEFT JOIN 
    Reply r ON p.id = r.postId -- rule(Reply::postId, ...)
WHERE 
    p.id IN (1, 2, 3); -- withCorrelationIdResolver(PostDetails::id)