Invoquer d'autres services

Les services Zato peuvent s'invoquer mutuellement de manière synchrone (self.invoke) ou asynchrone (self.invoke_async), ce qui vous permet de choisir si le service invoquant est bloqué en attendant la réponse ou si l'autre service doit être exécuté en arrière-plan.

Notez que dans ce dernier cas, vous ne recevrez pas directement une réponse. En revanche, lorsque vous invoquez un autre service de manière asynchrone, vous recevez un ID de corrélation que le service invoqué recevra également afin que sa réponse, le cas échéant, puisse être corrélée ultérieurement, à l'aide d'autres mécanismes Zato, spécifiques à votre application.

Comment transmettre une demande à un autre service

Le passage d'une requête est plus pratique si un autre service utilise Simple IO (SIO), dans ce cas, il est possible d'utiliser n'importe quel type d'entrée, par exemple une classe de données, un dictionnaire Python ou tout autre objet Python arbitraire peut être envoyé à un autre service.

from zato.server.service import Service

class MyService(Service):
    def handle(self):

        # A regular dictionary will do when invoking an SIO service
        input_data = {'cluster_id': 1}

        response = self.invoke('zato.security.get-list', input_data)
        for item in response.zato_security_get_list_response:
            self.logger.info(item.name)

Utilisez le paramètre 'data_format' si un service s'attend à ce que les données entrantes soient dans un format de données particulier, tel que JSON ou CSV.

# stdlib
from json import dumps

# Zato
from zato.common import DATA_FORMAT
from zato.server.service import Service

class MyService(Service):
    def handle(self):

        input_data = {'customer_id': 123, 'phone_no': '123-456-789'}
        service_name = 'invoking.my-service2'

        response = self.invoke(service_name, input_data, data_format=DATA_FORMAT.JSON)
        self.logger.info(response)

Identique au précédent mais effectué de manière asynchrone:

# stdlib
from json import dumps

# Zato
from zato.common import DATA_FORMAT
from zato.server.service import Service

class MyService(Service):
    def handle(self):

        input_data = {'customer_id': 123, 'phone_no': '123-456-789'}
        service_name = 'invoking.my-service2'

        cid = self.invoke_async(service_name, input_data, data_format=DATA_FORMAT.JSON)
        self.logger.info(cid)

class MyService2(Service):
    def handle(self):
        # Note how the payload is a Python dictionary
        self.logger.info(self.request.payload['customer_id'])

Réponses à la lecture

Les services SIO produisent des dictionnaires en tant que réponses et vous pouvez choisir de les utiliser directement ou de convertir une réponse en un Bunch afin d'utiliser la notation par points lors de l'accès aux éléments de la réponse. Ainsi, les exemples ci-dessous sont équivalents.

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):
    def handle(self):
        response = self.invoke('invoking.my-service2')
        self.logger.info(response['my_response_elem']['cust_name'])

class MyService2(Service):
    class SimpleIO:
        input_required  = 'cust_id'
        output_required = 'cust_name'
        response_elem = 'my_response_elem'

    def handle(self):
        self.response.payload.cust_name = 'Alexis Smith'

Lorsque vous invoquez un service de manière asynchrone, vous ne savez pas quand sa réponse sera produite.

Ainsi, la réponse d'une invocation asynchrone est l'ID de corrélation que le service invoqué recevra.

Vous pouvez utiliser l'ID de corrélation renvoyé pour corréler les réponses asynchrones lorsqu'elles sont disponibles - la manière dont cela est effectué dépend de votre application.

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):
    def handle(self):
        cid = self.invoke_async('invoking.my-service2')
        self.logger.info('Got CID %s', cid)

class MyService2(Service):
    def handle(self):
        self.logger.info('My CID is %s', self.cid)
INFO - Got CID c37780e779666e59ed284f92
INFO - My CID is c37780e779666e59ed284f92