Schedule a demo

REST channels

A REST channel connects an incoming HTTP request to one of your services. When a client calls your API endpoint, Zato routes the request to the service you specified, passes along any parameters, and returns the service's response.

Creating a channel

In Dashboard, go to Connections → Channels → REST and click Create:

The key fields:

  • Name - identifies this channel in logs and the Dashboard
  • URL path - the endpoint clients call, e.g. /api/customers
  • Service - which service handles requests to this URL
  • Data format - typically JSON for REST APIs
  • Security - optionally require authentication

Using data models

The most common way to handle REST requests is with data models. Define your request and response as Python dataclasses, and Zato handles JSON parsing and serialization automatically:

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

# stdlib
from dataclasses import dataclass

# Zato
from zato.server.service import Model, Service

@dataclass(init=False)
class CreateOrderRequest(Model):
    customer_id: str
    product_id: str
    quantity: int

@dataclass(init=False)
class CreateOrderResponse(Model):
    order_id: str
    status: str

class CreateOrder(Service):

    input = CreateOrderRequest
    output = CreateOrderResponse

    def handle(self):
        request = self.request.input  # type: CreateOrderRequest

        # Create the order using input data
        order_id = self.invoke('orders.create',
            customer_id=request.customer_id,
            product_id=request.product_id,
            quantity=request.quantity
        )

        # Build response
        response = CreateOrderResponse()
        response.order_id = order_id
        response.status = 'created'

        self.response.payload = response
curl -X POST http://localhost:11223/api/orders \
  -d '{"customer_id": "CUST-001", "product_id": "PROD-123", "quantity": 2}'

Benefits of data models:

  • Type checking - your IDE catches errors before runtime
  • Auto-serialization - JSON parsing and response formatting handled automatically
  • OpenAPI generation - export your API definitions for documentation
  • Validation - use after_created method for custom validation logic

For optional fields, use optional from zato.common.typing_:

from zato.common.typing_ import optional

@dataclass(init=False)
class CreateOrderRequest(Model):
    customer_id: str
    product_id: str
    quantity: int
    notes: optional[str] = None  # not required

Path parameters

Use curly braces to capture parts of the URL as parameters. For a URL path like /api/customers/{customer_id}/orders/{order_id}, Zato extracts both values and makes them available in your service:

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

# Zato
from zato.server.service import Service

class GetCustomerOrder(Service):

    def handle(self):
        customer_id = self.request.http.params['customer_id']
        order_id = self.request.http.params['order_id']

        order = self.invoke('orders.get', customer_id=customer_id, order_id=order_id)
        self.response.payload = order
curl http://localhost:11223/api/customers/CUST-001/orders/ORD-123

Query string parameters

Query string parameters are also available through self.request.http.params:

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

# Zato
from zato.server.service import Service

class SearchOrders(Service):

    def handle(self):
        status = self.request.http.params.get('status', 'all')
        limit = int(self.request.http.params.get('limit', 100))

        orders = self.invoke('orders.search', status=status, limit=limit)
        self.response.payload = orders
curl "http://localhost:11223/api/orders?status=pending&limit=10"

JSON request body

For POST and PUT requests with JSON bodies, Zato parses the JSON automatically. Access the data through self.request.payload:

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

# Zato
from zato.server.service import Service

class CreateCustomer(Service):

    def handle(self):
        name = self.request.payload['name']
        email = self.request.payload['email']

        customer = self.invoke('customers.create', name=name, email=email)
        self.response.payload = customer
curl -X POST http://localhost:11223/api/customers \
  -d '{"name": "Alice Smith", "email": "alice@example.com"}'

Restricting HTTP methods

By default, a channel accepts any HTTP method. To restrict it, select a specific method in the channel configuration.

For more control, implement verb-specific handlers in your service - this lets one service handle GET, POST, PUT, and DELETE differently on the same URL.

Data format

Set the channel's data format to match what clients send:

  • JSON - Zato parses incoming JSON and serializes responses automatically. This is the typical choice for REST APIs. See request and response handling for details.

  • Form data - for HTML form submissions or webhooks sending form-encoded data. Access fields through self.request.http.POST. For file uploads, see file handling.

Learn more