Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way to specify a reference to identity using annotation #81

Closed
zambrovski opened this issue May 24, 2022 · 5 comments
Closed
Assignees
Labels
module: cqrs / es CQRS and Event Sourcing support module: ddd Domain-Driven Design related support type: enhancement New feature or request
Milestone

Comments

@zambrovski
Copy link
Contributor

zambrovski commented May 24, 2022

Short

Introduce a new stereotype IdentityRef expressing a reference to a Identity as annotation.

Description

I stumbled upon an interesting question implementing command dispatching in CQRS. The command model accessed via aggregate root needs to be able to build an identifier from the context of a command to target the correct aggregate / entity.

A very easy way to target is to specify the target identifier inside the command. Firstly, I thought I could use Identifier or @Identity from jmolecules-ddd for this purpose, but it seems to be very strange... The command itself is an immutable value object and putting a field inside of it marked with @Identity seems to be confusing... A better approach is to use a different stereotype IdentityRef (as a annotation) to express the "pointer-to-identity" semantics.

Look on the follow example:

@Command(namespace = "customer", name = "UpdateCustomerProfile")
data class UpdateCustomerProfileCommand(
  @IdentityRef
  val customerId: CustomerId,
  val firstName: FirstName,
  val lastName: LastName
)

@AggregateRoot
class CustomerProfile {

  @Identity
  lateinit var customerId: CustomerId

  @CommandHandler(namespace = "customer", name = "UpdateCustomerProfile")
  fun handle(command: UpdateCustomerProfileCommand) {
    // ...  
  }
}

Is the Association marker interface is exactly designed for this? Then I think the definition of the association with an annotation should be possible:

/**
 * Marks the reference to identity.
 * Carries optional the identity type and the identifiable type.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Documented
public @interface IdentityRef {

    /**
     * Defines identity type.
     *
     * @return class defining the identity type.
     */
    Class<?> identityType() default void.class;

    /**
     * Defines the aggregate type.
     *
     * @return class defining the identifiable type (entity or aggregate).
     */
    Class<?> identifiableType() default void.class;
}
@zambrovski zambrovski changed the title Provide a way to specify a reference to identity Provide a way to specify a reference to identity: IdentityRef May 24, 2022
@zambrovski zambrovski changed the title Provide a way to specify a reference to identity: IdentityRef IdentityRef: provide a way to specify a reference to identity using annotation May 24, 2022
@odrotbohm odrotbohm changed the title IdentityRef: provide a way to specify a reference to identity using annotation Provide a way to specify a reference to identity using annotation Jun 1, 2022
@odrotbohm
Copy link
Member

You're right. In the type-based model, Association is what would model this, if you wanted to go beyond declaring the simple identifier field. I guess we could introduce an Association annotation, too, to keep symmetry between the two models (we already have that for AggregateRoot, Entity etc.).

What exactly would the purpose of the identityType attribute be? Isn't that – by definition – the type of the field?

@odrotbohm odrotbohm added the lifecycle: waiting-for-feedback Feedback by the original reporter needed label Jun 1, 2022
@odrotbohm odrotbohm self-assigned this Jun 1, 2022
@zambrovski
Copy link
Contributor Author

I agree with everything you wrote. You are absolutely right, the identityType is not required... Should I provide a PR then? How the annotation should be called? Are you ok with Association` then?

@zambrovski
Copy link
Contributor Author

To tell you what I'm currently building: it is Axon Framework byte buddy integration. For support of Axon Framework @TargetAggregateIdentifier I would use the @Association annotation then...

@odrotbohm
Copy link
Member

I agree with everything you wrote. You are absolutely right, the identityType is not required... Should I provide a PR then? How the annotation should be called? Are you ok with Association` then?

I would happily have a look at a PR. Association is just fine. I am wondering whether we want to be consistent with @Identity in allowing both annotations on methods, likely the getter, too.

To tell you what I'm currently building: it is Axon Framework byte buddy integration. For support of Axon Framework @TargetAggregateIdentifier I would use the @Association annotation then...

Nice! Looking forward to seeing that PR as well!

zambrovski added a commit to holixon/jmolecules that referenced this issue Jun 2, 2022
odrotbohm pushed a commit that referenced this issue Jun 7, 2022
This commit adds an annotation equivalent of the Association type for both Java and Kotlin.
odrotbohm added a commit that referenced this issue Jun 7, 2022
Renamed identifiableType attribute to aggregateType as the reference must be towards aggregates only. Fix license headers and Javadoc including references to other concepts (annotation flavors instead of type ones).
@odrotbohm
Copy link
Member

#82 has been polished and merged.

@odrotbohm odrotbohm added this to the 1.6 milestone Jun 20, 2022
@odrotbohm odrotbohm added type: enhancement New feature or request module: ddd Domain-Driven Design related support module: cqrs / es CQRS and Event Sourcing support and removed lifecycle: waiting-for-feedback Feedback by the original reporter needed labels Jun 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module: cqrs / es CQRS and Event Sourcing support module: ddd Domain-Driven Design related support type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants