Schedule a demo

Request and response objects

Request and response objects encapsulate information regarding the data a service receives and produces. Both objects will always exist for each service invocation but their payload can be empty - it is perfectly fine for a service not to accept any input data nor to create output either.

Overview

All services always have access to the attributes that describe in a general way the request being handled. Additionally, protocol-specific attributes, such as self.request.http, cover details pertaining to information that is specific to a particular protocol.

Most commonly accessed attributes are:

AttributeDescription
self.request.inputUsed to access incoming data if data models are used
self.request.payloadThe parsed request body as a dict - use for arbitrary JSON like webhooks
self.request.raw_requestThe raw request body exactly as received, prior to any parsing

Common attributes

Attributes listed in this section are available to all services, regardless of what kind of a channel they are invoked over, be it HTTP, scheduler, or any other.

AttributeDescription
self.requestAlong with self.channel, one of the main attributes describing incoming messages
self.request.raw_requestInput message exactly as it was received, byte-for-byte, prior to any transformations or parsing attempts
self.request.inputInput message after parsing it into a channel-specific data format. For JSON messages, this will be a Bunch object. Available only if data models are used.
self.request.payloadThe parsed request body. For JSON channels, this is a dict parsed from the incoming JSON. Use this when receiving arbitrary JSON (e.g. webhooks) without declaring an input attribute.
self.request.cidCorrelation ID for the current request - useful for logging and tracing
self.request.data_formatData format of the request, e.g. 'json' or 'xml'
self.request.transportTransport type used for the request
self.channelAlong with self.request, describes data and metadata about incoming messages. Unlike self.request, this attribute is the same for all requests coming through the same channel, i.e. it describes details of the channel itself rather than each individual message received.
self.channel.idUnique ID of the channel
self.channel.nameName of the channel the request was received through
self.channel.typeType of the channel - will be equal to one of the constants in zato.common.CHANNEL
self.chanAlias to self.channel
self.channel.securityDescribes a security definition attached to the channel, if any is at all
self.channel.security.nameName of the security definition
self.channel.security.usernameUsername used to invoke the channel, if applicable for a particular security type
self.channel.security.typeType of the security definition - will be equal to one of the constants in zato.common.SEC_DEF_TYPE
self.channel.secAlias to self.channel.security

HTTP-specific attributes

AttributeDescription
self.request.httpThe attribute to use to access HTTP-specific information
self.request.http.methodHTTP method used to invoke the service
self.request.http.GETAll GET parameters as a Bunch object, each value is either an exact one received or a list of values if there was more than one for a given key
self.request.http.POSTAll POST parameters as a Bunch object, each value is either an exact one received or a list of values if there was more than one for a given key. Available only if there is no data format set for channel.
self.request.http.pathURL path that the request was received through, e.g. /customer/123 in "https://localhost:17010/customer/123"; the value does not include a query string
self.request.http.paramsA dict-like object with a concatenation of query string and path parameters. Available even if data models are not used.
self.request.http.user_agentThe User-Agent header from the HTTP request
self.request.http.get_form_data()Returns form data from multipart requests as a dictionary
self.wsgi_environWhile not belonging directly to self.request.http, each service can always have access to the full WSGI dictionary of data and metadata about the request

More information

  • Consult the dedicated chapter with programming examples for more details.
  • To learn more about data models, click here

Overview

All services produce responses through their self.response attribute. Unlike with requests, there are no protocol-specific sub-attributes.

The most general way to create a response, and one that is always possible, is to assign a string or Unicode object to self.response.payload, e.g. as a result of manual serialization.

However, if using SimpleIO or if a channel's definition is JSON or XML, it is also possible for Zato to serialize objects directly, e.g. from dicts or SQLAlchemy objects.

Response attributes

All of the attributes and methods are always available to all services, regardless of the protocol they are invoked through though in the case of HTTP-specific ones, using them will be a no-op if the service is not invoked through HTTP.

AttributeDescription
self.responseThe main attribute via which responses are produced
self.response.payloadThe object to which responses are assigned, i.e. this is the attribute through which a service's business data is returned, such as a JSON message
self.response.status_code(HTTP only) An integer status code such as 200 or 401 to return in response
self.response.content_encoding(HTTP only) Sets response's Content-Encoding header value
self.response.content_type(HTTP only) Sets response's Content-Type header value
self.response.headers(HTTP only) A dictionary of header name/value to set in the response

self.response.payload

Assiging to self.response.payload lets one return responses from services. It can be done in several ways:

By assigning a string/unicode object directly. This approach is always available:

def handle(self):
    self.response.payload = '{"id":123, "name":"John Doe"}'

If using SimpleIO, all the attributes can be assigned to as they appear in the SimpleIO definition, either one, as a dictionary or as a list. Serialization to JSON or XML will be done by Zato automatically, depending on service's channel definition.

def handle(self):
    self.response.payload = {'id':123, 'name':'John Doe'}

To return a list of objects, attach it to self.response.payload, as above:

def handle(self):
    data = [
        {'id':123, 'name': 'John Doe'},
        {'id':456, 'name': 'Jane Xi'},
    ]
    self.response.payload = data

Assigning attributes individually:

def handle(self):
    self.response.payload.id = 123
    self.response.payload.name = 'John Doe'

If using SimpleIO, it is also possible to assign SQLAlchemy objects directly from an SQL query:

def handle(self):

    # Get user from database
    user = session.query(UserModel).\
        filter(UserModel.id==123).\
        one()

    # Assign the user object directly to response
    self.response.payload = user

More information

  • Consult the dedicated chapter with programming examples for more details.
  • To learn more about SimpleIO, click here