Search code examples
javacqrsaxon

How to send a command to an aggregate without knowledge about the identifier?


I have a question regarding mapping of a RESTful APIs and aggregates/entities in Axon.

Let’s say we’re in the cinema domain and start with a movie context encapsulated in a microservice. We’ve a Movie entity (aggregate) and a bunch of related commands and events.

@Aggregate
class Movie {

  @AggregateIdentifier
  private MovieId movieId;

  // omitted handlers, getters and setters

}

The related URL could look like /movies/<movieId>

Now I would like to introduce a new context/microservice for rating of movies. Movie ratings are related to a movie and a movie has no knowledge about their existence. But at the end I would like to address the ratings via the movie represented by it’s id. The URL could look like this /movies/<movieId>/ratings

So the entity might look somehow like this:

@Aggregate
class MovieRatings {

  @AggregateIdentifier
  private MovieRatingsId movieRatingsId;

  // the related movie
  private MovieId movieId;

  // a list of movie related ratings
  private List<Rating> movieRatings;

  // omitted handlers, getters and setters
}

The question is, does it make sense to create such an aggregate here? If no, how could an cqrs-based-alternative look like? And if yes, how can I address it via a command (e.g. AddRating) fired e.g. in my controller if I only know the movie identifier?


Solution

  • Thanks to @Zeljko Vujaklija and @Mzzl for the hints! I've adjusted the MovieRating aggregate:

    @Aggregate
    class MovieRating {
    
      @AggregateIdentifier
      private MovieRatingsId movieRatingsId;
    
      // the related movie
      private MovieId movieId;
    
      private Rating rating;
    
      // omitted handlers, getters and setters
    }
    

    And just use the movieId to query the movie related ratings. A simple POST to movies/<movieId>/ratings with the rating in body creates a movie rating and a GET retrieves the related data. Even editing of ratings using /movies/<movieId>ratings/<ratingId> would be possible.