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.
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:
| Attribute | Description |
|---|---|
| self.request.input | Used to access incoming data if data models are used |
| self.request.payload | The parsed request body as a dict - use for arbitrary JSON like webhooks |
| self.request.raw_request | The raw request body exactly as received, prior to any parsing |
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.
| Attribute | Description |
|---|---|
| self.request | Along with self.channel, one of the main attributes describing incoming messages |
| self.request.raw_request | Input message exactly as it was received, byte-for-byte, prior to any transformations or parsing attempts |
| self.request.input | Input 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.payload | The 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.cid | Correlation ID for the current request - useful for logging and tracing |
| self.request.data_format | Data format of the request, e.g. 'json' or 'xml' |
| self.request.transport | Transport type used for the request |
| self.channel | Along 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.id | Unique ID of the channel |
| self.channel.name | Name of the channel the request was received through |
| self.channel.type | Type of the channel - will be equal to one of the constants in zato.common.CHANNEL |
| self.chan | Alias to self.channel |
| self.channel.security | Describes a security definition attached to the channel, if any is at all |
| self.channel.security.name | Name of the security definition |
| self.channel.security.username | Username used to invoke the channel, if applicable for a particular security type |
| self.channel.security.type | Type of the security definition - will be equal to one of the constants in zato.common.SEC_DEF_TYPE |
| self.channel.sec | Alias to self.channel.security |
| Attribute | Description |
|---|---|
| self.request.http | The attribute to use to access HTTP-specific information |
| self.request.http.method | HTTP method used to invoke the service |
| self.request.http.GET | All 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.POST | All 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.path | URL 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.params | A dict-like object with a concatenation of query string and path parameters. Available even if data models are not used. |
| self.request.http.user_agent | The User-Agent header from the HTTP request |
| self.request.http.get_form_data() | Returns form data from multipart requests as a dictionary |
| self.wsgi_environ | While 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 |
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.
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.
| Attribute | Description |
|---|---|
| self.response | The main attribute via which responses are produced |
| self.response.payload | The 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 |
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:
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.
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:
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