Modules > Custom modules / Portable services

Portable services

A module’s behavior can be enhanced by the functionality of portable services. They allow starting and using custom microservices from modules.

A portable service contains the address of the microservice image to be deployed, its internal settings, and settings in the cluster.

Add a portable service

You can add a portable service to a module on the Services tab in the module’s settings. Here you can also edit or delete an existing service.

Portable service settings

  • Name. Name that will be displayed in the user interface.
  • Unique service name. Name that will be used in code or scripts to access the service. It is set once when the service is created and cannot be changed later.
  • Image address. URL of a Docker image. If the image is stored in Docker Hub, you can use a short relative path. If the image requires authentication, you need to specify the account login and token.
  • HTTP port. Port for communication with the microservice. The default port is 3000. When specifying the port, read the microservice’s documentation to determine which port to choose.
  • Number of instances. The number of microservice instances that are going to be deployed. When you change the number of instances, please note that ELMA365 itself doesn’t support any type of service replication. If it is not incorporated in the microservice, each of the instances will be entirely separate from others.
  • Environment variables. Here you can set up environment variables of the microservice. If configuration of the microservice with environment variables is available, you can use this tool to change the microservice’s settings. To find out whether you can use this functionality, see the microservice’s documentation.

Environment variables can be set during development, but you can also give the end user an opportunity to change them. To do that, you can create a template when filling out the value, specifying a property of the module. For example, if you want to let the user set the value of the requesttimeout environment variable, you first need to create a property in the module for specifying this value. Let’s name the property serviceTimeout. Then you need to go to the portable service and add the requesttimeout environment variable and set the following template for it: {$serviceTimeout}.

Note that when you add or edit environment variables, the microservice is restarted.

Liveness. This option allows you to use a Kubernetes probe to automatically restart a microservice in case of failure. Whether you can use a Liveness probe depends on the microservice. Read its documentation before including Liveness probes and selecting their types.

Readliness. This option allows you to use a Kubernetes probe to prevent the microservice from accepting requests before it is fully initialized. Whether you can use a Readiness probe depends on the microservice. Read its documentation before including Readiness probes and selecting their types.

начало внимание

Please take your time to carefully configure your portable services. If the settings are incorrect, and the Kubernetes response is invalid, the microservice will be considered inoperable and restarted no matter what its status actually is. We recommend avoiding probes if possible if you aren’t fully aware of why and how you need to use them and what the consequences are.

конец внимание

Enable or disable a microservice

When a module is enabled, all the microservices added to it are started. When the module is disabled, the microservices will be stopped and deleted.

If one microservice image is deployed from different modules within one company, there will be two different microservice instances.

If one microservice image is deployed from one module in different companies, there will also be two different microservice instances.

Microservice monitor

To track the statuses of microservices, open a module’s page. If the module is enabled, the page will show a list of microservices added to the module and information about them.

The Monitor lists all the microservices set by portable services. The information includes data about the image that the container is deployed from and about the number and current status of the replicas. If the Kubernetes cluster can provide metrics, data about resource consumption will also be shown.

Portable services don’t store state

At the moment, storing the state of microservices is not supported in portable services. This means that when a microservice stops, data from it will be lost.

Keep this in mind when choosing microservices for your needs. For example, you should only use a database microservice to store data temporarily. When a microservice is stopped or restarted, the data in the database will be reset.

This is also true for storing files, logs saved as files, etc.

Access to microservices

Scripts

To communicate with microservices, you can use the API provided in scripts. It is only available in server scripts and only within the module that the microservice belongs to, for example, in its widgets and business processes. Microservices cannot be accessed in client scripts. Services can be accessed using Namespace.services. If the module doesn’t contain portable services, this namespace will not appear among the autocomplete suggestions in the script.

To communicate with the microservice, use the fetch() method.

You can send a simple GET request without additional parameters specifying a relative path to the microservice API as the main parameter.

const res = await Namespace.services.vap.fetch("/SayHello");
if (res.ok) {
const resText = await res.text();
}

If you want to send a request of a different type, specify additional parameters, or set the request’s headers and body, use the fetch() method and pass FetchRequest as its second parameter:

const res = await Namespace.services.vap.fetch("/RememberMe", {
        method: 'POST',
        headers: {
            Authorization: 'myToken',
            },
        body: JSON.stringify({
            name: 'John',
            age: 27,
        })
    } );

When writing scripts, you may need to check a microservice’s state. To do that, you can use the status() method. It will return the ServiceStatus enum value with the information about the current status.

const info = await Namespace.services.vap.status();

Communication between two portable services

If the developer of the microservice allowed for communication between two microservices within a module, you can configure an access path from Portable service #1 to Portable service #2 using environment variables. To do that, open Portable service #1 and add an environment variable with the name specified in the documentation of Microservice #1. In this variable, specify the template for the name of Portable service #2. For example, {$_srv_serv2}.

Export and import

You can only export or import a module with portable services if Portable services are unlocked.

Found a typo? Highlight the text, press ctrl + enter and notify us