ruk·si

Go
Middlewares

Updated at 2013-12-03 04:46

Middleware is a function in a function call stack. They are more frequently use in Node.js and Java, but can easily be implemented in Go. They are usually used on webservers with HTTP request and HTTP response as parameters.

package main

import (
    "fmt"
    "errors"
)

type Middleware func(input string) (string, error)

type MiddlewareStack []Middleware

func (self *MiddlewareStack) Add(mw Middleware) {
    *self = append(*self, mw)
}

func (self *MiddlewareStack) Execute(input string) (string, error) {
    for _, middleware := range *self {
        output, err := middleware(input)
        if err != nil {
            return input, err
        }
        input = output
    }
    return input, nil
}

func main() {

    // Create a stack from the middlewares.
    var stack MiddlewareStack
    stack.Add(func(input string) (string, error){
        return input + " first", nil
    })
    stack.Add(func(input string) (string, error){
        return "second " + input, nil
    })

    // Execute the middleware stack with some input.
    input := "Hello!"
    fmt.Printf("Input: %s\n", input)
    outputOne, errOne := stack.Execute(input)
    if errOne == nil {
        fmt.Printf("Output: %s\n\n", outputOne)
    }

    // Add something that fails it and execute again.
    stack.Add(func(input string) (string, error){
        return input, errors.New("Middleware error.")
    })
    stack.Add(func(input string) (string, error){
        return "third " + input, nil
    })
    fmt.Printf("Input: %s\n", input)
    outputTwo, errTwo := stack.Execute(input)
    if errTwo == nil {
        fmt.Printf("Output: %s\n", outputTwo)
    } else {
        fmt.Printf("Output: %s\n", outputTwo)
        fmt.Printf("Error: %s\n", errTwo)
    }
}

Sources