Skip to content

Middleware

Two types of middleware exist: adapters and handlers. Adapters are used to adapt the data coming in and out from the channel, while handlers are used to process the data coming in from the channel. Although the concept is similar, adapters and handlers are different in the way they are executed within the pipeline.

For data coming through the channel input, both middleware types can be applied.

graph LR;
    channelInput((Input)) --> a1[/Adapter/]
    subgraph adapters
    a1 --> a2[/Adapter/]
    end
    a2 --> h1[/Handler/]
    a2 --> h2[/Handler/]

For data going through the channel output, however, only adapters are used. An internal handler that executes at the end of this pipeline is responsible for sending the data to the channel's socket.

graph LR;
    openChannel((Channel)) --> a1[/Adapter/]
    subgraph adapters
    a1 --> a2[/Adapter/]
    end
    a2 --> channelOutput([Output])

Characteristics

Unless there are very specific needs, middleware components should inherit from the abstract classes provided instead of implementing the interfaces directly. The base class for all middleware components (adapters and handlers) does a few things for us that won't be available when implementing the interfaces directly. This includes

  • Type checking
  • Type mutation

Type checking is essentially making sure the type of the data received is intended for the middleware. If it's not, the middleware component is not executed. If the component is an adapter, the data is automatically forwarded to the next middleware component in the pipeline.

Type mutation is the ability to change the data type, if compatible with the expected data of the middleware component. All components already deal with IByteBuffer <--> Byte[] and T <--> IEnumerable<T> mutations, but they also provide an opportunity to change/extend this behaviour.

Adapters vs Handlers

Because adapters and handlers are so similar, there might be a temptation to do everything with adapters. And while that's feasable, it's not recommended. Adapters should be used to adapt data and handlers to handle data.

  • Adapters adapt and forward data
  • Handlers handle data
  • Adapters can run at any point in the pipeline
  • Handlers run at the end of the pipeline
  • Data with type T is forwarded to the next (single) adapter in the pipeline
  • Data with type T can be forwarded to multiple handlers

Learn more about adapters and handlers.