Best way to call an external system

I’m trying to figure out the best way to handle calling an external system, i’m not sure if this code below is the best way to do it, because for example in case the database of projection is deleted how can i replay the events

@Aggregate
public class HtsAggregate {

    @AggregateIdentifier
    private String externalId;
    private String userId;
    private String phoneNumWallet;
    private String countryIndicator;
    private String branchId;

    public HtsAggregate() {
    }

    @CommandHandler
    public HtsAggregate(CreateCreditCardCommand cmd) {
        apply(new CreditCardCreatedEvent(cmd.externalId, cmd.userId, cmd.phoneNumWallet,
            cmd.countryIndicator, cmd.branchId));
    }

    @EventSourcingHandler
    protected void on(CreditCardCreatedEvent evt) {
        this.externalId = evt.externalId;
        this.userId = evt.userId;
        this.phoneNumWallet = evt.phoneNumWallet;
        this.countryIndicator = evt.countryIndicator;
        this.branchId = evt.branchId;
    }
   
}

@EventHandler
public void on(CreditCardCreatedEvent event) {
   try {
      final Object response = webClient.post().uri(url).bodyValue(event).retrieve().bodyToMono(Object.class).block();
      repoDone.save(response);
    } catch(Exception e) { 
      repoError.save(e.getMessage());
   }
}

Hi,

I am not an Axon developer, but I do have some thoughts about this.

If you are calling an external service, you usually might want to make sure that replaying the event handler does not call the external service again (keyword: DisallowReplay). That however leads to a read model which cannot be reset.

In our application we sometimes call the external service either directly in the aggregate (in the CommandHandler) or in a subscribing event handler (same transaction). If you do this and mark the succesful call with an event, you have a resetable read model again.

In either way you should make sure that your external service is idempotent (if you have control over this). This makes it easier to deal with failures, especially when you call this service from an event handler which might be retried by Axon in case of a failure.

Best regards

Nils

2 Likes