simplesourcing / simplesource

Simple Sourcing is an API for building event sourcing systems
Apache License 2.0
61 stars 8 forks source link

EventSourcedClient setup #36

Open forficate opened 4 years ago

forficate commented 4 years ago

EventSourcedClient

new EventSourcedClient()
                .withKafkaConfig(...)
               .addCommands(...)
               .build()

Essentially returns a big map of <String,Object>.

This means if you have the below class:

public class Somthing {
  Something(CommandAPI<String, AccountCommand> commandApi) {

  }
}

To pass in the constructor arg you need to:

new SimplesourceAccountWriteRepository(commandAPISet.getCommandAPI("account")

Again this means we are pulling values based on strings.

It also doesn't play to nice with Java like frameworks, take spring boot:

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public CommandAPISet commandAPISet(Config config){
        CommandAPISet result = new EventSourcedClient()
                .withKafkaConfig(builder ->
                        builder
                                .withKafkaApplicationId(config.kafkaGropId)
                                .withKafkaBootstrap(config.kafkaBootstrapServers)
                                .build()
                )
                .<String, AccountCommand>addCommands(builder ->
                        builder
                                .withClientId(config.kafkaGropId)
                                .withCommandResponseRetention(3600L)
                                .withName("account")
                                .withSerdes(ACCOUNT_COMMAND_SERDES)
                                .withResourceNamingStrategy(new PrefixResourceNamingStrategy())
                                .withTopicSpec(1, 1)
                ).build();

        simpleSourceComandApiSetStarted.set(true);
        return result;
    }

   @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public AccountWriteRepository accountWriteRepository(CommandAPISet commandAPISet) {
        return new SimplesourceAccountWriteRepository(commandAPISet.getCommandAPI("account"));
    }

It'd be nice if we could loose the builder stuff with addCommands and just do:

CommandAPI<String, AccountCommand> accountCommandApi = new CommandApi(...)
CommandAPI<String, BlahtCommand> blahCommandApi = new CommandApi(...)
szoio commented 4 years ago

Agree with this in general. There's no real reason why there needs to be a CommandAPISet` that groups command APIs. This class could probably go altogether.

Then rather call createCommandApi on the EventSourcedClient for each CommandAPI.

It's not like on the KStream side where they form a single topology. Each client is separate per aggregate.

Then for the Spring stuff:

  1. Have a Bean for the Kafka config.
  2. A bean for each of the CommandAPIs
  3. A bean for each WriteRepository Maybe 2 and 3 can be one bean, so the WriteRepository just creates the command API it needs from the Kafka config.

I'm Ok with the builder pattern though. In this particular case (i.e. as it currently is) it's not prescribed, as there is a addCommands(final CommandSpec<K, C> spec) method.