View on GitHub

TFG-DDD-Theoretical

Theoretical introductory information research about DDD, hex. architecture and CQRS

layout: page title: “query-handling” permalink: /query-handling

Query bus ❓ 🚐

This one was the trickiest part to put on code. The Axon query bus wasn’t my cup of tea so I decided to create a custom one using the axon eventBus but forcing it to have one and only one queryHandler lstener by using the java generics.

package com.shared.domain;

import org.springframework.stereotype.Service;

@Service
public interface QueryBus <T extends QueryHandler> {
	public <R extends Response>R ask(Query query);
}

Then the implementation in the infrastructure layer:

package com.shared.infrastructure;

import org.axonframework.eventhandling.EventBus;
import org.axonframework.eventhandling.GenericEventMessage;
import org.springframework.stereotype.Service;
import com.shared.domain.Query;
import com.shared.domain.QueryBus;
import com.shared.domain.QueryHandler;
import com.shared.domain.Response;

@Service
public class QueryBusImplementation <T extends QueryHandler>implements QueryBus {

	private EventBus queryBus;
	private T handler;
	
	public QueryBusImplementation(EventBus queryBus,T handler) {
		this.queryBus = queryBus;
		this.handler  = handler;
	}
	
  @override
	public Response ask(Query query) {
		this.queryBus.publish(GenericEventMessage.asEventMessage(query));
		return this.handler.handle(query);
	}
	
}

Query handling ❓ ✋

The controller, which is always a get in queries:

@RestController
public class IncidencesGetOneIncidenceController {

  //THE QUERY BUS IS FORCED TO DECLARE INE FINDER WHEN INJECTED. THE RELATION IS 1:1
	QueryBus<IncidenceFinder> queryBus;

	public IncidencesGetOneIncidenceController(QueryBus<IncidenceFinder>  queryBus) {
		this.queryBus = queryBus;
	}
	
	@GetMapping(value="/incidences/{id}")
	public ResponseEntity<HashMap<String, String>>find (@PathVariable String id) {
			
		try {
			FindIncidenceQuery     query    = new FindIncidenceQuery(id);	
			FoundIncidenceResponse response = queryBus.ask(query);
			
			return ResponseEntity.ok().body(new HashMap<String,String>() );
          
          //REST OF METHOD

At last, the query handler does its thing :

package com.incidences.application.find;

import org.axonframework.eventhandling.EventHandler;
import org.springframework.stereotype.Service;

import com.incidences.domain.Incidence;
import com.incidences.domain.IncidenceId;
import com.incidences.domain.IncidenceRepository;
import com.shared.domain.QueryHandler;

@Service
public class IncidenceFinder implements QueryHandler<FindIncidenceQuery, FoundIncidenceResponse>{

	IncidenceRepository repository;
	
	public IncidenceFinder(IncidenceRepository repository) {
		this.repository=repository;
	}
	
	@Override
	@EventHandler
	public FoundIncidenceResponse handle (FindIncidenceQuery request) throws IllegalArgumentException{
		
		IncidenceId id      = new IncidenceId(request.getId());
		Incidence incidence = repository.searchById(id);
		
		return new FoundIncidenceResponse(incidence);
	}

	
}

index