Check out the full series of Questions Management tutorial here.
In the previous tutorial, we prepared all the necessary configurations to build API add new question in the Composite Question Service: an object containing all the information of a question CompositeQuestion including Question, Category and Option; a CoreCategoryService interface with an implementation of CoreCategoryServiceImpl that deals with Core Category Service; a CoreQuestionService interface with a CoreQuestionServiceImpl implementation that handles the Core Question Service; a CoreOptionService interface with the implementation is CoreOptionServiceImpl that handles the Core Option Service; a CompositeQuestionService interface that handles Core Services; a CompositeQuestionController defines Composite Question Service APIs that start with “/question” and the Core Services information is configured in the application.properties file. Now, we are going to build this API!
To build API add new question, I first define a new method in the CoreQuestionService that calls the Core Question Service API to add a new question:
1 |
Mono<Question> addNewQuestion(Question question); |
The implementation of this method in the CoreQuestionServiceImpl class will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 |
@Override public Mono<Question> addNewQuestion(Question question) { WebClient webClient = WebClient.builder() .baseUrl(getServiceUrl()) .build(); return webClient.post() .uri("/question/add") .body(BodyInserters.fromObject(question)) .retrieve() .bodyToMono(Question.class); } |
Next we’ll also define a new method in the CompositeQuestionService that calls the addNewQuestion() method of the CoreQuestionService class and combines the information from the Core Category Service to return to the user after adding the new question.
The contents of this method are as follows:
1 |
Mono<CompositeQuestion> addNewQuestion(Question question); |
Implementation of this method:
1 2 3 4 5 6 7 |
@Override public Mono<CompositeQuestion> addNewQuestion(Question question) { return coreCategoryService.findById(question.getCategoryId()) .flatMap(category -> coreQuestionService.addNewQuestion(question) .map(q -> new CompositeQuestion(q.getId(), q.getDescription(), category, Collections.emptyList())) ).subscribeOn(Schedulers.elastic()); } |
As you can see, here we will check if the Category Id that this question belongs to exists in the system or not by calling the Core Category Service to look up Category by id. In case this Category exists, we just call the addNewQuestion() method of the CoreQuestionService class to add a new question.
The last thing we need to do is to add a new method to the CompositeQuestionController class to expose a POST request “/add” with the body data that is the content of the question that needs to be added.
1 2 3 4 |
@PostMapping("/add") public Mono<ResponseEntity<CompositeQuestion>> addNewQuestion(@RequestBody Question question) { } |
We only need to call the addNewQuestion() method of the CompositeQuestionService class:
1 2 3 4 5 6 |
@PostMapping("/add") public Mono<ResponseEntity<CompositeQuestion>> addNewQuestion(@RequestBody Question question) { return compositeQuestionService.addNewQuestion(question) .map(compositeQuestion -> ResponseEntity.ok(compositeQuestion)) .defaultIfEmpty(ResponseEntity.notFound().build()); } |
Here, in case you do not find the Category Id that this question belongs to, an HTTP 404 Not Found error will be returned to the user as you see in the code above.
OK, here we have finished building API add new question for Composite Question Service. Let’s test it.