Skip to main content

Unit 14: Implement Integration Service

đŸŽ¯Overview

In this course you will learn how to implement services in integration namespaces and how to call the Rest API of another microservice using your local IDE.

Outline​

After implementing the domain namespace, we continue with coding within the integration namespace. As explained in Unit 9: Design Service Integration, you can add an API dependency and define integration services that use this dependency to call operation from the referenced Rest API. Furthermore, integration services can have an input and an output entity and are able to throw business errors.
The code generation provides a class with one function for each integration service that we can immediately use, so we can dive straight into writing our business logic.

In general, the implementation of an integration service may contain the following pieces:

  • Retrieve the service input and map it to the request body of the referenced API operation.
  • Execute the API operation. If something goes wrong or a condition is not met, throw a business error.
  • Retrieve the response body of the API operation and map it to the output entity of the integration service.
  • Return or assign the service output.
â—ī¸info

Contrary to the design of our Orders service, we will first go through the integration namespace before the API namespace in the implementation phase. Reason is that we will use the integration service in the API operation we will implement in an upcoming course.

But in general you are free to go through the implememtation in any order you prefer. Because the IBM DevOps Solution Workbench has already generated the classes and method signatures of commands, services etc, it will not restrict your coding in any way if you use them before you provided their implementation code.

Prerequisites​

â—ī¸Alternative starting point for your training

If you rather want to use this course as a starting point of your training, you can use a different asset where all courses for designing and the courses for implementing the domain namespace are already completed.
In this case - depending on the chosen implementation language - use either asset "Order_Java_Code_0.2" or "Order_TypeScript_Code_0.2" to create a new project and to continue your training.
You can look up how to create a new project from the Order assets in the Preparation section in the Course Introduction.

Exercise​

Estimated time: 10 minutes
Exercise goal: After completing this course you are able to use integration services for processing calls of API operations of other microservices.
Supported languages: Java and TypeScript

In this exercise we will implement the integration service PostMail. It is responsible for sending a confirmation email via postMail API operation of the integrated Rest API in the SEMAIL service when a new customer order is created. In general, we are able to modify the behavior of the API operation inside our integration service for our whole Order service. But for our purposes, we will only forward the properties of the integration service input from to the request body of the called API operation.

Step 1: Implement the integration service​

The functionality of our integration service will include the following parts:

  • Use the input of our integration service to create a request body for the API method we want to call
  • Call the operation postMail of the SEMAIL service
  1. Open the file /src/main/java/<package-name>/integration/email/service/PostMail.java.
    You will see an auto-generated stub in which you can start your implementation.

    <package-name>: The package name of the Java project (e.g. com.knowis.orderjfinal)

    @Service("email_PostMail")
    public class PostMail extends PostMailBase {

    private static final Logger log = LoggerFactory.getLogger(PostMail.class);

    public PostMail(IntegrationEntityBuilder entityBuilder) {
    super(entityBuilder);
    }

    @NewSpan
    @Override
    public void execute(PostMailInput postMailInput) {
    log.info("PostMail.execute()");
    // TODO: Add your service implementation logic

    }
    }
  2. To reuse the Rest API of the SEMAIL service, we have to create a private field for a class called EmailsApiEmail. Additionally we have to add a constructor parameter that is then assigned to the private field.

    private final EmailsApiEmail apiEmail;

    public PostMail(
    IntegrationEntityBuilder entityBuilder,
    EmailsApiEmail apiEmail
    ) {
    super(entityBuilder);
    this.apiEmail = apiEmail;
    }

    Please use the auto-import function of your IDE to import the missing classes (and repeat this for the following steps). If you are not very familiar with imports, go back to Course 11 - Step 3: Import missing Classes for detailed information on class imports. Furthermore, you are free to compare your current imports with the recommended list of imports at the end of this section. Therefore, click here.

  3. After injecting the field, we will extend the execute method in the following steps. First, we will use the input of our integration service to create a request body for an API operation of the SEMAIL service.

    // Step 1: Create the request body for the API operation of the integrated service SEMAIL as an integration schema
    EmailMessage emailMessage = new EmailMessage()
    .messageFormat(EmailMessage.MessageFormatEnum.valueOf(postMailInput.getMessageFormat().name()))
    .sender(postMailInput.getSender())
    .addToItem(new EmailAddress().address(postMailInput.getTo()))
    .subject(postMailInput.getSubject())
    .message(postMailInput.getMessage());

    if(postMailInput.getCc() != null) {
    emailMessage.addCcItem(new EmailAddress().address(postMailInput.getCc()));
    }
  4. Then we will execute the postMail API operation with the request body. In case of an error, we will log its message.

    try {
    // Step 2: Execute the API operation of the integrated service
    this.apiEmail.postEmail(emailMessage, null);
    } catch (Exception e) {
    log.error("Failed to send email!", e);
    }
â„šī¸Recommended List of Imports

The provided list supports you to compare your current imports with the recommended list, especially if your IDE complains about errors in the code at this stage of the course.

List of Imports - File PostMail.java
// Fundamental 1: Generated classes based on design
import com.knowis.orderjfinal.sdk.integration.email.email.model.EmailAddress;
import com.knowis.orderjfinal.sdk.integration.email.email.model.EmailMessage;
import com.knowis.orderjfinal.sdk.integration.email.email.provider.EmailsApiEmail;
import com.knowis.orderjfinal.sdk.integration.email.service.PostMailBase;
import com.knowis.orderjfinal.sdk.integration.facade.IntegrationEntityBuilder;

// Fundamental 3: Built-in Java classes
import io.micrometer.tracing.annotation.NewSpan;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

The package name of the provided code is com.knowis.orderjfinal. All occurrences of this phrase have to be replaced with the package name of your project.

🌟Congratulations!

You have successfully implemented an integration service method to call an API endpoint from another microservice! In combination with the design in the Solution Designer, you are able to make use of integration services to call and process API operations of other microservices.

What's Next?​

In the next course you will learn how to implement an API operation that creates a new order.