Implementing your own middleware

A middleware class provides three handler functions, one for processing each of the three kinds of messages transports, applications and dispatchers typically send and receive (i.e. inbound user messages, outbound user messages, event messages) and three enabled functions for each of the types of messages

Although transport and application middleware potentially both provide the same sets of handlers, the two make use of them in slightly different ways. Inbound messages and events are published by transports but consumed by applications while outbound messages are opposite.

A middleware is required to subclass BaseMiddleware. This is a convenient definition of and set of common functionality for middleware classes. Custom setup should be done in setup() instead (if required). The config class can be overidden by replacing the config variable. You should overwrite handle_inbound(self, msg, connection)(), handle_outbound(self, msg, connection)(), handle_event(self, event, connection)(). handle_inbound() and handle_outbound() return vumi2 Messages handle_event() returns vumi2 Events

See logging and unidecoder examples

How your middleware is used inside Vumi:

While writing complex middleware, it may help to understand how a middleware class is used by Vumi transports and applications.

When a transport or application is started a list of middleware to load is read from the configuration. An instance of each piece of middleware is created and then setup() is called on each middleware object in order within the setup() of the worker

middleware_{type}_handler() function (e.g., middleware_outbound_handler) of BaseWorker of each message type. This function will: Filter the middleware list based on connector_name and the middleware’s {type}_enabled() method. Create a decorated handler function that sequentially applies each enabled middleware’s handle_{type}() method to the message. Return the decorated handler. This decorated handler is then used in setting up the connection