web icon indicating copy to clipboard operation
web copied to clipboard

design a middleware system for web.go

Open hoisie opened this issue 15 years ago • 6 comments

Lately I've been finding use cases for a middleware system. For example - generic cache-control handling and authentication

It will most likely follow the wsgi format -- something very simple for now

hoisie avatar Feb 15 '10 19:02 hoisie

Also, you can look at java servlets filters as another design choice with similar features. I can't really say if WSGI is simpler since I don't know it in great detail.

nileflowers avatar Apr 24 '10 16:04 nileflowers

It would be great to have a WSGI clone (or anything similar).

Ruby got a WSGI clone too some time ago called Rack. And it's also possible to use WSGI middleware for App Engine applications.

http://wsgi.org/wsgi/

tredoe avatar Jul 02 '10 18:07 tredoe

+1 for functionality similar to WSGI middlewares

flavius avatar Dec 21 '10 01:12 flavius

If someone is working on this, may I suggest the design draft be published as RFC before implementation?

yvsong avatar May 08 '11 15:05 yvsong

What about an express-like middleware system? IMO it's cleaner than WSGI-like middleware, because you use the same interface regardless of whether you're writing a handler or middleware. The change might be simpler too. It would consist of two additions; first, a way of adding global middleware that's activated for all requests. e.g. extending the hello world example:

package main

import (
    "github.com/hoisie/web"
    "fmt"
)

func someMiddleware(ctx *web.Context, urlArgs ...string) {
    fmt.Println("Middleware hit!")
}

func hello(ctx *web.Context, val string) { 
    for k,v := range ctx.Params {
        println(k, v)
    }
}   

func main() {
    web.Middleware(someMiddleware)
    web.Get("/(.*)", hello)
    web.Run("0.0.0.0:9999")
}

Then there'd also be a way to setup middleware on a per-endpoint basis, probably by changing methods like web.Get to accept multiple functions, e.g.

package main

import (
    "github.com/hoisie/web"
    "fmt"
)

func someMiddleware(ctx *web.Context, urlArgs ...string) {
    fmt.Println("Middleware hit!")
}

func hello(ctx *web.Context, val string) { 
    for k,v := range ctx.Params {
        println(k, v)
    }
}   

func main() {
    web.Get("/(.*)", someMiddleware, hello)
    web.Run("0.0.0.0:9999")
}

ysimonson avatar Jul 21 '13 18:07 ysimonson

Made a PR for the above proposal in #152 .

ysimonson avatar Jul 22 '13 13:07 ysimonson