. . .

Using other Services



In ApiOmat, you can execute CRUD operations on class objects of other services. To be able to communicate with other services, you first need to set up a used service relation. Once this is done, ApiOmat provides libraries for each used service that helps you to send requests to the used service's API. The library contains the model classes and an API client for each model.
The following sections describe how to set up your used service relation and how to use the service libraries to communicate with their API clients.

Please be aware of the inheritance and reference limitations which are described in Service Limitations.
Also: By default, all used service artifacts will be re-resolved every time you build your service.
The section "Automatic updating of used services" describes how this works, why it is done and how to change it.


Setting a used Service Library Relation

Ensure used Service Library is deployed to Host

Before setting a used service relation and before you can use the service library, you need to generate the library and deploy it to the Innkeeper service, which acts as a Maven repository for the artifacts.

To do this, you either can use the Dashboard functionality under Components > Services > Deploy Library or you just need to call the following Brewer REST endpoint:cURL

curl -X PUT $BREWER_BASE_URL/brewer/ms/$USEDSERVICE_NAME/v/$USEDSERVICE_VERSION/lib/deployToHost -u "$customerName:$customerPassword"

Once the library has been successfully generated and deployed, you can set the used service relation.
There are different ways to do this:

Option A) Automatic via Brewer-Maven-Plugin

The Brewer Maven plugin is a tool providing custom Maven goals that helps you to operate with your generated local service project. Amongst other things it provides you the addDependency goal in order to automatically do all the changes needed to add a used service as dependency.

To add a new used service dependency to your local generated service project you basically just need to call the following command within your service project's root directory:

pom.xml
mvn brewer:add-dependency -DserviceName=<usedServiceName> -DserviceVersion=<usedServiceVersion>

This will not only add the correct used service dependency to your pom.xml but also add the necessary configuration changes to your local project. Afterwards just update your local Maven project to retrieve all the needed dependencies like the usedService library.

You can now start to use the used service API client's and later deploy your finish implementation by calling mvn deploy (see Brewer Maven plugin documentation for more details).

Option B) Semi-Automatic via REST

This alternative option to create a used service relation between two services is to call a specific YAMBAS REST endpoint. Afterwards, the generated service project will contain all the project files you need.
However this is not supported under the following circumstances:

  • You already deployed your generated service to Innkeeper and downloaded it without setting the flag merge=false

  • You have your sources locally and downloaded the service via the brewer:download Maven goal

The reason for that behaviour is that we don't overwrite all files in this semi-automatic operation (such as pom.xml or application.yml) to give you more freedom during development.
Therefore, you'd have to download the generated service using the merge=false flag and manually merge the changes in pom.xml and application.yml, or adapt the files manually according to option C (see below).


To set a used service relation via REST, use the following YAMBAS endpoint:cURL

curl -X POST $YAMBAS_BASE_URL/yambas/rest/modules/$SERVICENAME/v/$SERVICEVERSION/parent -d "parentModuleName=$USEDSERVICE_NAME&parentModuleVersion=$USEDSERVICE_VERSION" -u "$customerName:$customerPassword"

To remove a used service relation, use the following REST endpoint:cURL

curl -X DELETE $YAMBAS_BASE_URL/yambas/rest/modules/$SERVICENAME/v/$SERVICEVERSION/parent/$USEDSERVICE_NAME/v/$USEDSERVICE_VERSION" -u "$customerName:$customerPassword"


Once the used service relation is set, you need to trigger the first generation of the service either by using the build action in the Dashboard or by calling Brewer's service generation REST endpoint (see step 5 in the Tutorial "Model your Service" or go to Brewer's usage documentation).
After generating and downloading your service, you can continue with integrating it into your IDE and skip option C to progress with the next section.

Option C) Manually

This section contains the steps you need to do manually which are done automatically in the previous options. In general, you just need to add the used service as a library dependency to the POM of your service and configure some Spring project features.
But let's go into detail:

Insert used Service Lib Dependency

First, check that the Innkeeper repositories to the artifacts are configured correctly within your POM. Normally, this should be done automatically by Brewer, but if you need to manually add these repositories, see the section Downloading and uploading your Service of the tutorial. The Innkeeper repositories are needed to locate the used service library we generated earlier.

Next, add the following Maven dependency to the POM of your generated service project:


pom.xml

<dependency>
<groupId>com.apiomat.microservice</groupId>
<artifactId>usedservice-lib</artifactId>
<version>1.0.0</version>
</dependency>

The artifactId consists of the used service name in lowercase followed by the suffix -lib. The version should match the service version you want to use.
After that, you need to update your Maven project to resolve the new dependency and get access to the other service.


Configure Feign Clients

We use Feign for communication between different service APIs. Feign is a declarative technology that simplifies web service client implementation (refer to the official Spring Cloud documentation to learn more about Feign).
Feign clients are used in our services to easily access other services' REST endpoints.

The EnableFeignClients annotation in the main class of the service specifies the packages to be scanned during application startup for available Feign client interfaces.
To enable Feign clients for your used service, add the base package path of the used service to the annotation.
In this example, you'd have to add com.apiomat.microservice.usedservice to the annotation of the class com.apiomat.microservice.myservice.MyServiceApplication:


com.apiomat.microservice.myservice.MyServiceApplication

@EnableFeignClients( basePackages = { "com.apiomat.microservice.myservice", "com.apiomat.microservice.usedservice" } )
public class MyServiceApplication extends SpringBootServletInitializer
{
[...]


Additionally, the Feign clients need some configuration details which are set in the application.yml file of your generated service that uses the service library:


application.yml

For each used service, add the following:

apiomat:
  service:
    discovery:
      uses:
        {USED_SERVICE_NAME}:
	      name: {{USED_SERVICE_NAME}}
	      version: "[{{USED_SERVICE_VERSION}}]"

For example:

apiomat:
  service:
    discovery:
      uses:
        HobbitService:
	      name: HobbitService
	      version: "[1.0.0]"

Now you are ready to call the used service library to access its classes.


Communicating with other Services

This section shows you how to call the used service via the provided API clients
The service library contains all model classes of the used service and an API client for each model. These API clients provide methods to create, update, read and delete objects of the used service classes by automatically sending REST requests to the used service's API.

Technically, the API client classes are the Feign clients that have been configured and can be injected as Spring components. The following example shows you how to call the read endpoint of a used service class:com.apiomat.microservice.myservice.service.MyClassApiServiceImpl

[...]
import com.apiomat.microservice.myservice.model.MyClass;
import com.apiomat.microservice.usedservice.model.UsedServiceClass;
import com.apiomat.microservice.usedservice.service.UsedServiceClassApiClient;
 
[...]
public class MyClassApiServiceImpl extends AbstractMyClassApiServiceImpl
{
@Autowired
private UsedServiceClassApiClient usedServiceClient;
 
[...]
 
@Override
public MyClass load( final String appName, final String id )
{
/* example: the UsedClass object is loaded via id to get the foreignId for the facadeObj */
final UsedServiceClass usedClass = this.usedServiceClient.getSpecificUsedServiceClass( appName, id, false )
 
final MyClass facadeObj = new MyClass( );
facadeObj.setForeignId( usedClass.getForeignId( ) )
 
return facadeObj;
}
}

Other methods to execute CRUD operations can be found within your IDE with the help of the auto-complete feature on the injected ApiClient.

Automatic updating of used Services

As used services do not have SNAPSHOT versions, Maven does not automatically retrieve updates from the hosting service. This can be very inconvenient for development, as you would have to create a new version of the service for every change or manually retrieve the updated artifact(s).

To solve this problem, we have added the Maven goal dependency:purge-local-repository to the POM of every generated service. This goal updates used service artifacts by deleting and re-retrieving them every time the service is built (e.g. with mvn package).

By default, the goal is applied to every used service. If you only want to apply it to specific services, you can use the configuration properties <include> and <exclude> of the goal to do so (see linked documentation above for details).
For example, here is a case where only one out of three used services is being updated:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>com.apiomat.microservice</groupId>
<artifactId>batservice</artifactId>
<packaging>war</packaging>
<name>BatService</name>
<version>1.0.0</version>
<description></description>
 
<!-- ... -->
 
<!-- used services -->
<dependency>
<groupId>com.apiomat.microservice</groupId>
<artifactId>redservice-lib</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.apiomat.microservice</groupId>
<artifactId>blueservice-lib</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Still in development -->
<dependency>
<groupId>com.apiomat.microservice</groupId>
<artifactId>greenservice-lib</artifactId>
<version>1.1.6</version>
</dependency>
<!-- end used services -->
 
<!-- ... -->
 
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>update-used-services</id>
<phase>process-sources</phase>
<goals>
<goal>purge-local-repository</goal>
</goals>
<configuration>
<includes>
<include>com.apiomat.microservice:greenservice-lib</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
 
<!-- ... -->
 
</project>