Direct client
Key takeaways
Direct client | A component that calls a controller directly in the same memory space. |
Controller | Custom component used to define a method that is called by the direct client. |
References | Component used to store and locate component references. |
DependencyResolver | Component used to resolve component references. |
Introduction
A direct client is a component that calls a controller directly in the same memory space. In general, it is used when multiple microservices are deployed in a single container (monolith system) and communication between them can be done by direct calls. Within Pip.Services, the DirectClient component is used to create it.
This tutorial will help you understand how this class works. First, we will see how to create a simple controller that contains a method that prints “Hello world”. Then, we will learn how to create a direct client that connects to this controller and allows us to use the method previously defined in our controller. Finally, we will run our program and see the results.
The controller
Our controller class is very simple and, for the purpose of this example, has a function named “my_method”, which prints “Hello world”. The following code shows how this class is defined and how to create an instance of it.
import { ConfigParams, IConfigurable, IReferenceable, IReferences } from "pip-services3-commons-nodex";
export async function main() {
// Instantiation
let myController = new MyController();
}
export class MyController implements IConfigurable, IReferenceable {
public configure(config: ConfigParams): void {
}
public setReferences(references: IReferences): void {
}
public myMethod(): void {
console.log('Hello world');
}
}
using PipServices3.Commons.Refer;
using PipServices3.Commons.Config;
class Program
{
static void Main(string[] args)
{
// Instantiation
var myController = new MyController();
}
}
class MyController : IConfigurable, IReferenceable
{
public void Configure(ConfigParams config)
{
}
public void SetReferences(IReferences references)
{
}
public void myMethod()
{
Console.WriteLine("Hello world");
}
}
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cref "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)
func main() {
// Instantiation
myController := &MyController{}
}
type MyController struct {
}
func (c *MyController) Configure(ctx context.Context, config *cconf.ConfigParams) {
}
func (c *MyController) SetReferences(ctx context.Context, references cref.IReferences) {
}
func (c *MyController) MyMethod() {
fmt.Println("Hello world")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
void main(List<String> argument) {
// Instantiation
var myController = MyController();
}
class MyController implements IConfigurable, IReferenceable {
void configure(ConfigParams config) {}
void setReferences(IReferences references) {}
void myMethod() {
print('Hello world');
}
}
# Pre-requisites
from pip_services3_commons.refer import Descriptor, IReferences, IReferenceable
from pip_services3_commons.config import IConfigurable
# Controller
class MyController(IConfigurable, IReferenceable):
def __init__(self):
pass
def configure(self, config):
pass
def set_references(self, references: IReferences):
pass
def my_method(self):
print("Hello world")
# Instantiation
myController = MyController()
The direct client
Now that we have our controller, we can construct a direct client that communicates with it and calls “my_method”.
To achieve this, we do the following process. First, we create a reference to the controller via two components: References and DependencyResolver. This last class is used to give a name to our controller’s reference and is added in the init() method. Then, in the setReferences() method, we receive a References object, which is used to associate the client to the controller. Lastly, we create a method that invokes “my_method” from the controller. Once our class is defined, we create an instance of it. The following code shows how to do this.
// Pre-requisites
import { ConfigParams, DependencyResolver, Descriptor, IConfigurable, IReferenceable, IReferences } from "pip-services3-commons-nodex";
import { DirectClient } from "pip-services3-rpc-nodex";
// Direct client
export class MyDirectClient extends DirectClient<MyController> {
_dependencyResolver = new DependencyResolver();
public constructor() {
super();
this._controller = null
this._dependencyResolver.put("controller", new Descriptor("pip-services", "controller", "*", "*", "1.0"))
}
public setReferences(references: IReferences): void {
this._dependencyResolver.setReferences(references);
this._controller = this._dependencyResolver.getOneRequired("controller");
}
}
// Instantiation
let client = new MyDirectClient();
// Pre-requisites
using PipServices3.Commons.Refer;
using PipServices3.Commons.Config;
using PipServices3.Rpc.Clients;
// Direct client
class MyDirectClient: DirectClient<MyController>
{
public MyDirectClient()
{
_controller = null;
_dependencyResolver.Put("controller", new Descriptor("pip-services", "controller", "*", "*", "1.0"));
}
public void setReferences(IReferences references)
{
this._dependencyResolver.SetReferences(references);
this._controller = _dependencyResolver.GetOneRequired<MyController>("controller");
}
public void myMethod()
{
_controller.myMethod();
}
}
// Instantiation
var client = new MyDirectClient();
// Pre-requisites
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cref "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
rpcclnt "github.com/pip-services3-gox/pip-services3-rpc-gox/clients"
)
// Direct client
type MyDirectClient struct {
*rpcclnt.DirectClient
dependencyResolver *cref.DependencyResolver
controller *MyController
}
func NewMyDirectClient() *MyDirectClient {
c := &MyDirectClient{}
c.dependencyResolver = cref.NewDependencyResolver()
c.dependencyResolver.Put(context.Background(), "controller", cref.NewDescriptor("pip-services", "controller", "*", "*", "1.0"))
return c
}
func (c *MyDirectClient) SetReferences(ctx context.Context, references cref.IReferences) {
c.dependencyResolver.SetReferences(ctx, references)
res, err := c.dependencyResolver.GetOneRequired("controller")
if err != nil {
panic(err)
}
c.controller = res.(*MyController)
}
func (c *MyDirectClient) MyMethod() {
c.controller.MyMethod()
}
// Instantiation
client := NewMyDirectClient();
// Pre-requisites
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_rpc/pip_services3_rpc.dart';
// Direct client
class MyDirectClient extends DirectClient<MyController> {
MyDirectClient() {
dependencyResolver.put('controller',
Descriptor('pip-services', 'controller', '*', '*', '1.0'));
}
@override
void setReferences(IReferences references) {
dependencyResolver.setReferences(references);
controller = dependencyResolver.getOneRequired<MyController>('controller');
}
void myMethod() {
controller.myMethod();
}
}
// Instantiation
var client = MyDirectClient();
# Pre-requisites
from pip_services3_rpc.clients import DirectClient
from pip_services3_commons.refer import Descriptor, IReferences, DependencyResolver
from pip_services3_commons.config import IConfigurable
# Direct client
class MyDirectClient(DirectClient):
_dependencyResolver = DependencyResolver()
def __init__(self):
super(MyDirectClient, self).__init__()
self._controller: MyController = None
self._dependencyResolver.put("controller", Descriptor("pip-services", "controller", "*", "*", "1.0"))
def set_references(self, references: IReferences):
self._dependencyResolver.set_references(references)
self._controller = self._dependencyResolver.get_one_required("controller")
def my_method(self):
self._controller.my_method()
# Instantiation
client = MyDirectClient()
Reference setting
The next step is to define the association between our reference in the client and the controller. The following code shows how to do it.
// Pre-requisites
import { References } from "pip-services3-commons-nodex";
// Reference setting
client.setReferences(References.fromTuples(
new Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController));
// Pre-requisites
using PipServices3.Commons.Refer;
// Reference setting
client.setReferences(References.FromTuples(
new Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController));
// Pre-requisites
import (
cref "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
)
// Reference setting
client := NewMyDirectClient()
client.SetReferences(context.Background(), cref.NewReferencesFromTuples(context.Background(),
cref.NewDescriptor("pip-services", "controller", "controller", "default", "1.0"), myController,
))
// Pre-requisites
import 'package:pip_services3_commons/pip_services3_commons.dart';
// Reference setting
client.setReferences(References.fromTuples([
Descriptor('pip-services', 'controller', 'controller', 'default', '1.0'),
myController
]));
# Pre-requisites
from pip_services3_commons.refer import References
# Reference setting
client.set_references(References.from_tuples(
Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController))
Calling “my_method”
Our aim is to call “my_method” from the client. We have made this possible by connecting the controller and the client. Thus, our final step is to call this method from the client with the following command:
client.myMethod();
client.myMethod();
client.MyMethod()
client.myMethod();
client.my_method()
Which after execution produces the following result:
Final code
The following code summarizes all the previous steps:
import { ConfigParams, DependencyResolver, Descriptor, IConfigurable, IReferenceable, IReferences, References } from "pip-services3-commons-nodex";
import { DirectClient } from "pip-services3-rpc-nodex";
export async function main() {
// Instantiation
let myController = new MyController();
// Instantiation
let client = new MyDirectClient();
// Reference setting
client.setReferences(References.fromTuples(
new Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController));
// Calling "my_method"
client.myMethod();
}
export class MyDirectClient extends DirectClient<MyController> {
_dependencyResolver = new DependencyResolver();
public constructor() {
super();
this._controller = null
this._dependencyResolver.put("controller", new Descriptor("pip-services", "controller", "*", "*", "1.0"))
}
public setReferences(references: IReferences): void {
this._dependencyResolver.setReferences(references);
this._controller = this._dependencyResolver.getOneRequired("controller");
}
public myMethod(): void {
this._controller.myMethod();
}
}
export class MyController implements IConfigurable, IReferenceable {
public configure(config: ConfigParams): void {
}
public setReferences(references: IReferences): void {
}
public myMethod(): void {
console.log('Hello world');
}
}
using System;
using PipServices3.Commons.Refer;
using PipServices3.Commons.Config;
using PipServices3.Rpc.Clients;
namespace ExampleApp
{
class Program
{
static void Main(string[] args)
{
// Instantiation
var myController = new MyController();
// Instantiation
var client = new MyDirectClient();
// Reference setting
client.setReferences(References.FromTuples(
new Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController));
client.myMethod();
}
}
class MyDirectClient: DirectClient<MyController>
{
public MyDirectClient()
{
_controller = null;
_dependencyResolver.Put("controller", new Descriptor("pip-services", "controller", "*", "*", "1.0"));
}
public void setReferences(IReferences references)
{
this._dependencyResolver.SetReferences(references);
this._controller = _dependencyResolver.GetOneRequired<MyController>("controller");
}
public void myMethod()
{
_controller.myMethod();
}
}
class MyController : IConfigurable, IReferenceable
{
public void Configure(ConfigParams config)
{
}
public void SetReferences(IReferences references)
{
}
public void myMethod()
{
Console.WriteLine("Hello world");
}
}
}
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cref "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
rpcclnt "github.com/pip-services3-gox/pip-services3-rpc-gox/clients"
)
func main() {
// Instantiation
myController := &MyController{}
// Instantiation
client := NewMyDirectClient()
// Reference setting
client.SetReferences(context.Background(), cref.NewReferencesFromTuples(context.Background(),
cref.NewDescriptor("pip-services", "controller", "controller", "default", "1.0"), myController,
))
// Calling "my_method"
client.MyMethod()
}
type MyDirectClient struct {
*rpcclnt.DirectClient
dependencyResolver *cref.DependencyResolver
controller *MyController
}
func NewMyDirectClient() *MyDirectClient {
c := &MyDirectClient{}
c.dependencyResolver = cref.NewDependencyResolver()
c.dependencyResolver.Put(context.Background(), "controller", cref.NewDescriptor("pip-services", "controller", "*", "*", "1.0"))
return c
}
func (c *MyDirectClient) SetReferences(ctx context.Context, references cref.IReferences) {
c.dependencyResolver.SetReferences(ctx, references)
res, err := c.dependencyResolver.GetOneRequired("controller")
if err != nil {
panic(err)
}
c.controller = res.(*MyController)
}
func (c *MyDirectClient) MyMethod() {
c.controller.MyMethod()
}
type MyController struct {
}
func (c *MyController) Configure(ctx context.Context, config *cconf.ConfigParams) {
}
func (c *MyController) SetReferences(ctx context.Context, references cref.IReferences) {
}
func (c *MyController) MyMethod() {
fmt.Println("Hello world")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_rpc/pip_services3_rpc.dart';
void main(List<String> argument) {
// Instantiation
var myController = MyController();
// Instantiation
var client = MyDirectClient();
client.setReferences(References.fromTuples([
Descriptor('pip-services', 'controller', 'controller', 'default', '1.0'),
myController
]));
client.myMethod();
}
class MyDirectClient extends DirectClient<MyController> {
MyDirectClient() {
dependencyResolver.put('controller',
Descriptor('pip-services', 'controller', '*', '*', '1.0'));
}
@override
void setReferences(IReferences references) {
dependencyResolver.setReferences(references);
controller = dependencyResolver.getOneRequired<MyController>('controller');
}
void myMethod() {
controller.myMethod();
}
}
class MyController implements IConfigurable, IReferenceable {
void configure(ConfigParams config) {}
void setReferences(IReferences references) {}
void myMethod() {
print('Hello world');
}
}
# Pre-requisites
from pip_services3_rpc.clients import DirectClient
from pip_services3_commons.refer import Descriptor, References, IReferences, IReferenceable, DependencyResolver
from pip_services3_commons.config import IConfigurable
# Direct client
class MyDirectClient(DirectClient):
_dependencyResolver = DependencyResolver()
def __init__(self):
self._controller: MyController = None
self._dependencyResolver.put("controller", Descriptor("pip-services", "controller", "*", "*", "1.0"))
super(MyDirectClient, self).__init__()
def set_references(self, references: IReferences):
self._dependencyResolver.set_references(references)
self._controller = self._dependencyResolver.get_one_required("controller")
def my_method(self):
self._controller.my_method()
# Instantiation
client = MyDirectClient()
# Controller
class MyController(IConfigurable, IReferenceable):
def __init__(self):
pass
def configure(self, config):
pass
def set_references(self, references: IReferences):
pass
def my_method(self):
print("Hello world")
# Instantiation
myController = MyController()
# Reference setting
client.set_references(References.from_tuples(
Descriptor("pip-services", "controller", "controller", "default", "1.0"), myController))
# Calling "my_method"
client.my_method()
Which, after running, produces the following outcome:
Wrapping up
In this tutorial, we have seen how to create a direct client by using the DirectClient component. To understand this class, we created a controller with a method that prints “Hello world”. Then, we created a client with the controller as a dependency and connected both components. Finally, we ran the created method from the client and saw the results.