HTTP Middleware

Video tutorial

  • Writing a middleware

Writing a middleware

RoadRunner HTTP server uses default Golang middleware model which allows you to extend it using custom or community-driven middleware. The simplest service with middleware registration would look like:

package middleware

import (

const PluginName = "middleware"

type Plugin struct{}

// to declare plugin
func (p *Plugin) Init() error {
	return nil

func (p *Plugin) Middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// do something
		// ...
		// continue request through the middleware pipeline
		next.ServeHTTP(w, r)

// Middleware/plugin name.
func (p *Plugin) Name() string {
	return PluginName

Middleware must correspond to the following interface and be named.

You have to register this service after in the container/plugin.go file in order to properly resolve dependency:

import (

func Plugins() []interface{} {
    return []interface{}{
    // ...
    // middleware
    // ...

Or you might use Velox to build the RR binary.

You should also make sure you configure the middleware to be used via the config or the command line otherwise the plugin will be loaded but the middleware will not be used with incoming requests.

    # provide the name of the plugin as provided by the plugin in the example's case, "middleware"
    middleware: [ "middleware" ]

PSR7 Attributes

You can safely pass values to ServerRequestInterface->getAttributes() using attributes package:

func (s *Service) Middleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		r = attributes.Init(r)
		attributes.Set(r, "key", "value")
		next.ServeHTTP(w, r)
Edit this page