Communication between components

How we can use the References class to communicate between different components.

Key takeaways

References Component used to store and retrieve component references.
Get methods Collection of several methods contained in the References class and used to retrieve stored component references. E.g. getOneRequired().
setReferences() Method available from the PrometheusCounters and PrometheusMetricsService classes and used to store component references in a References object.

Introduction

When using Pip.Services, a good programming practice is to use an external entity to handle the communication between different components. In this tutorial, you will learn how to do this by using the References class.

For this, we will first see the main characteristics and methods of the References component. Then, we will explain how this component is used in the example provided in the Prometheus tutorial and how it helps with the communication between different components. To conclude, we will summarize the learned concepts.

The References component

The References component is available via the Commons module. It’s used to store information on registered components and to pass this information to other components when requested.

Pre-requisites

To use this component, we must first import it. This can be done with the following command:

import { References } from "pip-services3-commons-nodex";
using PipServices3.Commons.Refer;
import (
    refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)
import 'package:pip_services3_commons/pip_services3_commons.dart';

from pip_services3_commons.refer import References
Not available

Creation

In order to create a References object, we need to create a component that can be added to it. Following the Prometheus example, we create a PrometheusMetricsService object. The code below shows how to do this:

import { ConfigParams } from "pip-services3-commons-nodex";
import { PrometheusMetricsService } from "pip-services3-prometheus-nodex";

let service = new PrometheusMetricsService();

service.Configure(ConfigParams.FromTuples(
    "connection.protocol", "http",
    "connection.host", "localhost",
    "connection.port", 8080
));

using PipServices3.Commons.Config;
using PipServices3.Prometheus.Services;

var service = new PrometheusMetricsService();

service.Configure(ConfigParams.FromTuples(
    "connection.protocol", "http",
    "connection.host", "localhost",
    "connection.port", 8080
));

import (
	"context"

	cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
	pservice "github.com/pip-services3-gox/pip-services3-prometheus-gox/services"
)

service := pservice.NewPrometheusMetricsService()

service.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
	"connection.protocol", "http",
	"connection.host", "localhost",
	"connection.port", 8080,
))
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_prometheus/pip_services3_prometheus.dart';


var service = PrometheusMetricsService();
  service.configure(ConfigParams.fromTuples([
    'connection.protocol',
    'http',
    'connection.host',
    'localhost',
    'connection.port',
    8080
  ]));

from pip_services3_prometheus.services import PrometheusMetricsService
from pip_services3_commons.config import ConfigParams

service = PrometheusMetricsService()

service.configure(ConfigParams.from_tuples(
    "connection.protocol", "http",
    "connection.host", "localhost",
    "connection.port", 8080
))
Not available

There are three main ways to create a References component. The first is to use the fromTuples() method. This static method allows us to add one or more references to our component. In the example below, we create a References component and add the service object previously created.

import { Descriptor, References } from "pip-services3-commons-nodex";

let references = References.fromTuples(
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
using PipServices3.Commons.Refer;

var references = References.FromTuples(
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
import (
    "context"
    refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)

references := refer.NewReferencesFromTuples(context.Background(),
	refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
)
import 'package:pip_services3_commons/pip_services3_commons.dart';

var references = References.fromTuples([
    Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '1.0'), service
]);
from pip_services3_commons.refer import Descriptor

references = References.from_tuples(
    Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
)
Not available

The second way is to create an instance of the References class and later on add the necessary references to it. The following code shows how to do this:

let references2 = new References();
var references2 = new References();
references := refer.NewEmptyReferences()
var references2 = References();
references2 = References()
Not available

Lastly, we can use the constructor with a tuple that includes a list of references, where odd elements are locators and even elements are component references. The following example shows how to create a References object that contains a reference to the previously created service object.

let references3 = new References([new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service]);
var references3 = new References(new object[] { new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service });
references3 := refer.NewReferences(context.Background(), []interface{}{refer.NewDescriptor("pip-services", "context-info", "default", "default", "1.0"), service})
var references3 = References([
    Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '1.0'), service
]);
references3 = References((Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service))
Not available

Main methods

The References class has several methods that allow us to store and retrieve data from an instance of it. They are:

find()

This method obtains all the component references that match a specific locator. In the example below, we ask for all those references that relate to our service object, and we obtain a reference to this component.

references.find(service, true);
references.Find(service, true);
references.Find(service, true)
references.find(service, true);
references.find(service, True)
Not available
getAll()

This method retrieves all the stored component references in the form of a list. In our example, it returns a list with a reference to the service object.

references.getAll();
references.GetAll()
references.GetAll()
references.getAll();
references.get_all()
Not available
getAllLocators()

This method obtains the locators corresponding to all the registered component references. In the example below, we get a Descriptor object containing information about the service object.

references.getAllLocators();
references.GetAllLocators()
references.GetAllLocators()
references.getAllLocators();
references.get_all_locators()
Not available
getOneOptional()

This method retrieves an optional component reference that matches a specified locator. In the example below, we obtain a reference to the stored service object.

references.getOneOptional(service);
references.GetOneOptional(service);
references.GetOneOptional(service)
references.getOneOptional(service);
references.get_one_optional(service)
Not available
getOneRequired()

This method gets a required component reference that matches a specified locator and throws a ReferenceException when no reference is found. In the following example, we request and obtain the service component.

references.getOneRequired(service);
references.GetOneRequired(service)
references.GetOneRequired(service)
references.getOneRequired(service);
references.get_one_required(service)
Not available
getOptional()

This method obtains all component references that match a specified locator. In the example below, we ask for the service component and obtain a list with it.

references.getOptional(service);
references.GetOptional(service);
references.GetOptional(service)
references.getOptional(service);
references.get_optional(service)
Not available
getRequired()

This method gets all component references that match a specified locator. If no reference is found, it throws a ReferenceException. In our example, it returns a reference to the stored service component.

references.getRequired(service);
references.GetRequired(service);
references.GetRequired(service)
references.getRequired(service);
references.get_required(service)
Not available
put()

This method adds a reference to the Reference component. In the example below, we add a reference to the service object defined earlier.

references2.put(new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service);
references2.Put(new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service);
references2.Put(context.Background(), refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service)
references2.put(
    Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '1.0'), service
);
references2.put(Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service)
Not available
remove()

This method removes a previously added reference that matches a specified locator. If many references match the locator, it removes only the first one. In the example below, it removes the reference to the service object previously added.

references2.remove(service);
references2.Remove(service);
references2.Remove(context.Background(), service)
references2.remove(service);
references2.remove(service)
Not available
removeAll()

This method removes all component references that match a specified locator. For example, the code below removes all references to the service component.

references.removeAll(service);
references.RemoveAll(service);
references.RemoveAll(context.Background(), service)
references.removeAll(service);
references.remove_all(service)
Not available

Example 1

In order to explain how the References component can help us to create communication channels for different components, we will use the example created in the Prometheus tutorial. There, we created a custom component named MyComponentA, a PrometheusCounters component that was used to create different counters, and a PrometheusMetricsService object that was used to create a webpage containing the counters' information under /metrics.

In the tutorial’s example, these three components are added to the References object via the setReferences() method. When needed, they are called via a get method. The figure below summarizes this structure.

figure 1

In that example, and in order to add the three components to the References object, we use the fromTuples() method. This method accepts one or more Descriptor objects, each containing information about a component, and the respective referenced object. The following code shows how this is done:

let context_info = new ContextInfo();
context_info.name = "Test";
context_info.description = "This is a test container";

let references = References.fromTuples(
    new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
    new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);

service.setReferences(references);
counters.setReferences(references);
using PipServices3.Commons.Refer;
using PipServices3.Components.Info;

var context_info = new ContextInfo();
context_info.Name = "Test";
context_info.Description = "This is a test container";

var references = References.FromTuples(
    new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
    new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);

service.SetReferences(references);
counters.SetReferences(references);
contextInfo := cinfo.NewContextInfo()
contextInfo.Name = "Test"
contextInfo.Description = "This is a test container"

references := refer.NewReferencesFromTuples(context.Background(),
	refer.NewDescriptor("pip-services", "context-info", "default", "default", "1.0"), contextInfo,
	refer.NewDescriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
	refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
)

service.SetReferences(context.Background(), references)
counters.SetReferences(context.Background(), references)
var context_info = ContextInfo();
context_info.name = 'Test';
context_info.description = 'This is a test container';

var references = References.fromTuples([
  Descriptor('pip-services', 'context-info', 'default', 'default', '1.0'),
  context_info,
  Descriptor('pip-services', 'counters', 'prometheus', 'default', '1.0'),
  counters,
  Descriptor(
      'pip-services', 'metrics-service', 'prometheus', 'default', '1.0'),
  service
]);

service.setReferences(references);
counters.setReferences(references);
from pip_services3_commons.refer import Descriptor
from pip_services3_components.info import ContextInfo

context_info = ContextInfo()
context_info.name = 'Test'
context_info.description = 'This is a test container'

references = References.from_tuples(
    Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
    Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
)

service.set_references(references)
counters.set_references(references)
Not available

Once we have our components in the References object, we can obtain them via any of the get methods available from this class. The code below shows how the MyComponentA class obtains the required counters:

class MyComponentA implements IReferenceable {
    public consoleLog: boolean = true; // console log flag
    private counters: CachedCounters;

    public constructor() {

        if (this.consoleLog)
            console.log("MyComponentA has been created.");
    }
    public setReferences(references: IReferences): void {
        this.counters = references.getOneRequired<CachedCounters>(
            new Descriptor("*", "counters", "*", "*", "*")
        );
    }
}
public class MyComponentA: IReferenceable
{
    public bool ConsoleLog = true; // console log flag

    private CachedCounters counters;
    public MyComponentA()
    {
        if (ConsoleLog)
            Console.WriteLine("MyComponentA has been created.");
    }

    public void SetReferences(IReferences references)
    {
        counters = references.GetOneRequired<CachedCounters>(
            new Descriptor("*", "counters", "*", "*", "*")
        );
    }
}
type MyComponentA struct {
	counters *pcount.PrometheusCounters

	ConsoleLog bool // console log flag
}

func NewMyComponentA() *MyComponentA {
	c := MyComponentA{
		ConsoleLog: true,
	}
	if c.ConsoleLog {
		fmt.Println("MyComponentA has been created.")
	}
	return &c
}

func (c *MyComponentA) SetReferences(references refer.IReferences) {
	p, err := references.GetOneRequired(
		refer.NewDescriptor("*", "counters", "prometheus", "*", "*"),
	)

	if p != nil && err == nil {
		c.counters = p.(*pcount.PrometheusCounters)
	}
}
class MyComponentA implements IReferenceable {
  bool consoleLog = true; // console log flag
  CachedCounters? counters;

  MyComponentA() {
    if (consoleLog) print('MyComponentA has been created.');
  }

  @override
  void setReferences(IReferences references) {
    counters = references.getOneRequired<CachedCounters>(
        Descriptor('*', 'counters', '*', '*', '*'));
  }
}
class MyComponentA(IReferenceable):
    console_log: bool = True  # console log flag

    def __init__(self):
        self._counters: PrometheusCounters = None
        if self.console_log:
            print("MyComponentA has been created.")

    # Added references for getting counters
    def set_references(self, references: IReferences):
        self._counters = references.get_one_required(
            Descriptor("*", "counters", "*", "*", "*")
        )
Not available

Similarly, if we check the source code for the PrometheusCounters class, we can see that the class gets the context information via the getOneOptional() method.

See PrometheusCounters

    /**
	 * Sets references to dependent components.
	 * 
	 * @param references 	references to locate the component dependencies. 
     */
    public setReferences(references: IReferences): void {
        this._logger.setReferences(references);
        this._connectionResolver.setReferences(references);

        let contextInfo = references.getOneOptional<ContextInfo>(
            new Descriptor("pip-services", "context-info", "default", "*", "1.0"));
        if (contextInfo != null && this._source == null) {
            this._source = contextInfo.name;
        }
        if (contextInfo != null && this._instance == null) {
            this._instance = contextInfo.contextId;
        }
    }

See PrometheusCounters

    /// <summary>
    /// Sets references to dependent components.
    /// </summary>
    /// <param name="references">references to locate the component dependencies.</param>
    public virtual void SetReferences(IReferences references)
    {
        _logger.SetReferences(references);
        _connectionResolver.SetReferences(references);

        var contextInfo = references.GetOneOptional<ContextInfo>(
            new Descriptor("pip-services3", "context-info", "default", "*", "1.0"));
            
        if (contextInfo != null && string.IsNullOrEmpty(_source))
            _source = contextInfo.Name;
        if (contextInfo != null && string.IsNullOrEmpty(_instance))
            _instance = contextInfo.ContextId;
    }

See PrometheusCounters

// SetReferences method are sets references to dependent components.
// - references  cref.IReferences
// references to locate the component dependencies.
func (c *PrometheusCounters) SetReferences(ctx context.Context, references cref.IReferences) {
	c.logger.SetReferences(ctx, references)
	c.connectionResolver.SetReferences(ctx, references)
	ref := references.GetOneOptional(
		cref.NewDescriptor("pip-services", "context-info", "default", "*", "1.0"))
	contextInfo, _ := ref.(*cinfo.ContextInfo)
	if contextInfo != nil && c.source == "" {
		c.source = contextInfo.Name
	}
	if contextInfo != nil && c.instance == "" {
		c.instance = contextInfo.ContextId
	}
}

See PrometheusCounters

  /// Sets references to dependent components.
  ///
  /// - [references] 	references to locate the component dependencies.
  @override
  void setReferences(IReferences references) {
    _logger.setReferences(references);
    _connectionResolver.setReferences(references);

    var contextInfo = references.getOneOptional<ContextInfo>(
        Descriptor('pip-services', 'context-info', 'default', '*', '1.0'));
    if (contextInfo != null && _source == null) {
      _source = contextInfo.name;
    }
    if (contextInfo != null && _instance == null) {
      _instance = contextInfo.contextId;
    }
  }

See PrometheusCounters

    def set_references(self, references: IReferences):
        """
        Sets references to dependent components.
        :param references: references to locate the component dependencies.
        """
        self.__logger.set_references(references)
        self.__connection_resolver.set_references(references)

        context_info = references.get_one_optional(Descriptor("pip-services", "context-info", "default", "*", "1.0"))
        if context_info is not None and self.__source is None:
            self.__source = context_info.name
        if context_info is not None and self.__instance is None:
            self.__instance = context_info.context_id
Not available

And the PrometheusMetricsService component obtains the context information via the getOneRequired() method:

See PrometheusMetricsService

    /**
	 * Sets references to dependent components.
	 * 
	 * @param references 	references to locate the component dependencies. 
     */
    public setReferences(references: IReferences): void {
        super.setReferences(references);

        this._cachedCounters = this._dependencyResolver.getOneOptional<PrometheusCounters>("prometheus-counters");
        if (this._cachedCounters == null)
            this._cachedCounters = this._dependencyResolver.getOneOptional<CachedCounters>("cached-counters");

        let contextInfo = references.getOneOptional<ContextInfo>(
            new Descriptor("pip-services", "context-info", "default", "*", "1.0"));

        if (contextInfo != null && (this._source == "" || this._source == undefined)) {
            this._source = contextInfo.name;
        }
        if (contextInfo != null && (this._instance == "" || this._instance == undefined)) {
            this._instance = contextInfo.contextId;
        }
    }

See PrometheusMetricsService

    /// <summary>
    /// Sets references to dependent components.
    /// </summary>
    /// <param name="references">references to locate the component dependencies.</param>
    public override void SetReferences(IReferences references)
    {
        base.SetReferences(references);
        _cachedCounters = _dependencyResolver.GetOneOptional<PrometheusCounters>("prometheus-counters");

        var contextInfo = references.GetOneOptional<ContextInfo>(
            new Descriptor("pip-services3", "context-info", "default", "*", "1.0"));
            
        if (contextInfo != null && string.IsNullOrEmpty(_source))
            _source = contextInfo.Name;
        if (contextInfo != null && string.IsNullOrEmpty(_instance))
            _instance = contextInfo.ContextId;
        if (_cachedCounters == null)
            _cachedCounters = _dependencyResolver.GetOneOptional<CachedCounters>("cached-counters");
    }

See PrometheusMetricsService

// SetReferences is sets references to dependent components.
// Parameters:
//   - references cref.IReferences
// references to locate the component dependencies.
func (c *PrometheusMetricsService) SetReferences(ctx context.Context, references cref.IReferences) {
	c.RestService.SetReferences(ctx, references)

	resolv := c.DependencyResolver.GetOneOptional("prometheus-counters")
	c.cachedCounters = resolv.(*pcount.PrometheusCounters).CachedCounters
	if c.cachedCounters == nil {
		resolv = c.DependencyResolver.GetOneOptional("cached-counters")
		c.cachedCounters = resolv.(*ccount.CachedCounters)
	}
	ref := references.GetOneOptional(
		cref.NewDescriptor("pip-services", "context-info", "default", "*", "1.0"))
	contextInfo := ref.(*cinfo.ContextInfo)

	if contextInfo != nil && c.source == "" {
		c.source = contextInfo.Name
	}
	if contextInfo != nil && c.instance == "" {
		c.instance = contextInfo.ContextId
	}
}

See PrometheusMetricsService

  /// Sets references to dependent components.
  ///
  /// - [references] 	references to locate the component dependencies.
  @override
  void setReferences(IReferences references) {
    super.setReferences(references);

    _cachedCounters = dependencyResolver
        .getOneOptional<PrometheusCounters>('prometheus-counters');
    _cachedCounters ??=
        dependencyResolver.getOneOptional<CachedCounters>('cached-counters');

    var contextInfo = references.getOneOptional<ContextInfo>(
        Descriptor('pip-services', 'context-info', 'default', '*', '1.0'));

    if (contextInfo != null && (_source == '' || _source == null)) {
      _source = contextInfo.name;
    }
    if (contextInfo != null && (_instance == '' || _instance == null)) {
      _instance = contextInfo.contextId;
    }
  }

See PrometheusMetricsService

    def set_references(self, references: IReferences):
        """
        Sets references to dependent components.
        :param references: references to locate the component dependencies.
        """
        super().set_references(references)

        self.__cached_counters = self._dependency_resolver.get_one_required('prometheus-counters')
        if self.__cached_counters is None:
            self.__cached_counters = self._dependency_resolver.get_one_required('cached-counters')

        context_info = references.get_one_required(Descriptor("pip-services", "context-info", "default", "*", "1.0"))

        if context_info is not None and (self.__source == '' or self.__source is None):
            self.__source = context_info.name

        if context_info is not None and (self.__instance == '' or self.__instance is None):
            self.__instance = context_info.context_id
Not available

Example 2

An important advantage of Pip.Services is that once we have a set of references, we can define from general to specific queries.

For example, let’s assume that we have created the following References object:

let references = References.fromTuples(
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "2.0"), service2,
    new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    new Descriptor("pip-services", "context-info", "default", "*", "1.0"), new ContextInfo("tutorial", "Example context conmponent"),
    new Descriptor("pip-services", "logger", "console", "default", "1.0"), new ConsoleLogger()
);
var references = References.FromTuples(
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
    new Descriptor("pip-services", "metrics-service", "prometheus", "default", "2.0"), service2,
    new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    new Descriptor("pip-services", "context-info", "default", "*", "1.0"), new ContextInfo("tutorial", "Example context conmponent"),
    new Descriptor("pip-services", "logger", "console", "default", "1.0"), new ConsoleLogger()
);
references := refer.NewReferencesFromTuples(context.Background(),
	refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
	refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "2.0"), service2,
	refer.NewDescriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
	refer.NewDescriptor("pip-services", "context-info", "default", "*", "1.0"), cinfo.NewContextInfo(),
	refer.NewDescriptor("pip-services", "logger", "console", "default", "1.0"), clog.NewConsoleLogger(),
)
var references = References.fromTuples([
  Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '1.0'), service,
  Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '2.0'), service2,
  Descriptor('pip-services', 'counters', 'prometheus', 'default', '1.0'), counters,
  Descriptor('pip-services', 'context-info', 'default', '*', '1.0'), ContextInfo('tutorial', 'Example context conmponent'),
  Descriptor('pip-services', 'logger', 'console', 'default', '1.0'), ConsoleLogger()
]);
references = References.from_tuples(
    Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
    Descriptor("pip-services", "metrics-service", "prometheus", "default", "2.0"), service2,
    Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
    Descriptor("pip-services", "context-info", "default", "*", "1.0"),  ContextInfo('tutorial', 'Example context conmponent'),
    Descriptor("pip-services", "logger", "console","default", "1.0"),  ConsoleLogger()
)
Not available

Then, we can generate different types of queries, such as:

a. Get all service objects

If we want to obtain all objects of a specific type, such as all our service objects, we can create this query by specifying the name of the type and considering all other fields generic. Generic fields are specified by using a star to indicate “any”. For example, to obtain the two services, we can do the following query:

references.find(new Descriptor("*", "metrics-service", "*", "*", "*"), true);
references.Find(new Descriptor("*", "metrics-service", "*", "*", "*"), true);
references.Find(refer.NewDescriptor("*", "metrics-service", "*", "*", "*"), true)
references.find(Descriptor('*', 'metrics-service', '*', '*', '*'), true);
references.find(Descriptor("*", "metrics-service", "*", "*", "*"), True)
Not available

b. Get a specific service object

The Reference object also allows us to work with several versions of a component. For example, in our Reference object, we have defined two versions of the service. Therefore, if we want to choose version 2.0, we just need to create a reference to it. The example below shows how to do this.

references.getOneOptional(new Descriptor("*", "metrics-service", "*", "*", "2.0"));
references.GetOneOptional(new Descriptor("*", "metrics-service", "*", "*", "2.0"));
references.GetOneOptional(refer.NewDescriptor("*", "metrics-service", "*", "*", "2.0"))
references.getOneOptional(Descriptor('*', 'metrics-service', '*', '*', '2.0'));
references.get_one_optional(Descriptor("*", "metrics-service", "*", "*", "2.0"))
Not available

c. Get all components in a group

If we need to obtain all the components in a group, we can specify the group’s name and consider all the other fields generic. Thus, if we want to obtain the five objects stored in the “pip-services” group, we can do:

references.getRequired(new Descriptor("pip-services", "*", "*", "*", "*"));
references.GetRequired(new Descriptor("pip-services", "*", "*", "*", "*"));
references.GetRequired(refer.NewDescriptor("pip-services", "*", "*", "*", "*"))
references.getRequired(Descriptor('pip-services', '*', '*', '*', '*'));
references.get_required(Descriptor("pip-services", "*", "*", "*", "*"))
Not available

d. Get a specific component

To get a specific component outside the references object, we just need to specify its name. The following example shows how to obtain the service component defined earlier.

let reference = references.getOneOptional(service);
var reference = references.GetOneOptional(service);
reference := references.GetOneOptional(service)
var reference = references.getOneOptional(service);
reference = references.get_one_optional(service)
Not available

Wrapping up

In this tutorial, we have learned how to use the References class to allow communication between different components. First, we saw how to create an instance of this class and use its different methods. Then, we understood how this component is used in the example defined in the Prometheus tutorial, where it works as a broker that stores information on registered components and passes it to other components when requested. Finally, we learned how to create different types of queries, from generic to specific ones.