README

Goji

GoDoc Build Status

Goji is a minimalistic web framework that values composability and simplicity.

This project has been superseded by a new version of Goji by the same author, which has very similar primitives and semantics, but has been updated to reflect several years of experience with this library and the surrounding Go ecosystem. This project is still well-loved and well-maintained, and will be for the foreseeable future, but new projects are encouraged to use goji.io instead.

Example

package main

import (
        "fmt"
        "net/http"

        "github.com/zenazn/goji"
        "github.com/zenazn/goji/web"
)

func hello(c web.C, w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
}

func main() {
        goji.Get("/hello/:name", hello)
        goji.Serve()
}

Goji also includes a sample application in the example folder which was artificially constructed to show off all of Goji's features. Check it out!

Features

  • Compatible with net/http
  • URL patterns (both Sinatra style /foo/:bar patterns and regular expressions, as well as custom patterns)
  • Reconfigurable middleware stack
  • Context/environment object threaded through middleware and handlers
  • Automatic support for Einhorn, systemd, and more
  • Graceful shutdown, and zero-downtime graceful reload when combined with Einhorn.
  • High in antioxidants

Stability

Goji's API is essentially frozen, and guarantees to never break compatibility with existing code (under similar rules to the Go project's guidelines). Goji is suitable for use in production, and has served billions of requests across several companies.

Is it any good?

Maybe!

There are plenty of other good Go web frameworks out there. Goji is by no means especially novel, nor is it uniquely good. The primary difference between Goji and other frameworks—and the primary reason I think Goji is any good—is its philosophy:

Goji first of all attempts to be simple. It is of the Sinatra and Flask school of web framework design, and not the Rails/Django one. If you want me to tell you what directory you should put your models in, or if you want built-in flash sessions, you won't have a good time with Goji.

Secondly, Goji attempts to be composable. It is fully composable with net/http, and can be used as a http.Handler, or can serve arbitrary http.Handlers. At least a few HTTP frameworks share this property, and is not particularly novel. The more interesting property in my mind is that Goji is fully composable with itself: it defines an interface (web.Handler) which is both fully compatible with http.Handler and allows Goji to perform a "protocol upgrade" of sorts when it detects that it is talking to itself (or another web.Handler compatible component). web.Handler is at the core of Goji's interfaces and is what allows it to share request contexts across unrelated objects.

Third, Goji is not magic. One of my favorite existing frameworks is Martini, but I rejected it in favor of building Goji because I thought it was too magical. Goji's web package does not use reflection at all, which is not in itself a sign of API quality, but to me at least seems to suggest it.

Finally, Goji gives you enough rope to hang yourself with. One of my other favorite libraries, pat, implements Sinatra-like routing in a particularly elegant way, but because of its reliance on net/http's interfaces, doesn't allow programmers to thread their own state through the request handling process. Implementing arbitrary context objects was one of the primary motivations behind abandoning pat to write Goji.

Is it fast?

Yeah, it is. Goji is among the fastest HTTP routers out there, and is very gentle on the garbage collector.

But that's sort of missing the point. Almost all Go routers are fast enough for almost all purposes. In my opinion, what matters more is how simple and flexible the routing semantics are.

Goji provides results indistinguishable from naively trying routes one after another. This means that a route added before another route will be attempted before that route as well. This is perhaps the most simple and most intuitive interface a router can provide, and makes routes very easy to understand and debug.

Goji's router is also very flexible: in addition to the standard Sinatra-style patterns and regular expression patterns, you can define custom patterns to perform whatever custom matching logic you desire. Custom patterns of course are fully compatible with the routing semantics above.

It's easy (and quite a bit of fun!) to get carried away by microbenchmarks, but at the end of the day you're not going to miss those extra hundred nanoseconds on a request. What matters is that you aren't compromising on the API for a handful of CPU cycles.

Third-Party Libraries

Goji is already compatible with a great many third-party libraries that are themselves compatible with net/http, however some library authors have gone out of their way to include Goji compatibility specifically, perhaps by integrating more tightly with Goji's web.C or by providing a custom pattern type. An informal list of such libraries is maintained on the wiki; feel free to add to it as you see fit.

Contributing

Please do! I love pull requests, and I love pull requests that include tests even more. Goji's core packages have pretty good code coverage (yay code coverage gamification!), and if you have the time to write tests I'd like to keep it that way.

In addition to contributing code, I'd love to know what you think about Goji. Please open an issue or send me an email with your thoughts; it'd mean a lot to me.

Expand ▾ Collapse ▴

Documentation

Overview

    Package goji provides an out-of-box web server with reasonable defaults.

    Example:

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/zenazn/goji"
    	"github.com/zenazn/goji/web"
    )
    
    func hello(c web.C, w http.ResponseWriter, r *http.Request) {
    	fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
    }
    
    func main() {
    	goji.Get("/hello/:name", hello)
    	goji.Serve()
    }
    

    This package exists purely as a convenience to programmers who want to get started as quickly as possible. It draws almost all of its code from goji's subpackages, the most interesting of which is goji/web, and where most of the documentation for the web framework lives.

    A side effect of this package's ease-of-use is the fact that it is opinionated. If you don't like (or have outgrown) its opinions, it should be straightforward to use the APIs of goji's subpackages to reimplement things to your liking. Both methods of using this library are equally well supported.

    Goji requires Go 1.2 or newer.

    Index

    Constants

    This section is empty.

    Variables

    View Source
    var DefaultMux *web.Mux

      The default web.Mux.

      Functions

      func Abandon

      func Abandon(middleware web.MiddlewareType) error

        Abandon removes the given middleware from the default Mux's middleware stack. See the documentation for web.Mux.Abandon for more information.

        func Connect

        func Connect(pattern web.PatternType, handler web.HandlerType)

          Connect adds a CONNECT route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

          func Delete

          func Delete(pattern web.PatternType, handler web.HandlerType)

            Delete adds a DELETE route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

            func Get

            func Get(pattern web.PatternType, handler web.HandlerType)

              Get adds a GET route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

              func Handle

              func Handle(pattern web.PatternType, handler web.HandlerType)

                Handle adds a route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                func Head(pattern web.PatternType, handler web.HandlerType)

                  Head adds a HEAD route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                  func Insert

                  func Insert(middleware, before web.MiddlewareType) error

                    Insert the given middleware into the default Mux's middleware stack. See the documentation for web.Mux.Insert for more information.

                    func NotFound

                    func NotFound(handler web.HandlerType)

                      NotFound sets the NotFound handler for the default Mux. See the documentation for web.Mux.NotFound for more information.

                      func Options

                      func Options(pattern web.PatternType, handler web.HandlerType)

                        Options adds a OPTIONS route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                        func Patch

                        func Patch(pattern web.PatternType, handler web.HandlerType)

                          Patch adds a PATCH route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                          func Post

                          func Post(pattern web.PatternType, handler web.HandlerType)

                            Post adds a POST route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                            func Put

                            func Put(pattern web.PatternType, handler web.HandlerType)

                              Put adds a PUT route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                              func Serve

                              func Serve()

                                Serve starts Goji using reasonable defaults.

                                func ServeListener

                                func ServeListener(listener net.Listener)

                                  Like Serve, but runs Goji on top of an arbitrary net.Listener.

                                  func ServeTLS

                                  func ServeTLS(config *tls.Config)

                                    Like Serve, but enables TLS using the given config.

                                    func Trace

                                    func Trace(pattern web.PatternType, handler web.HandlerType)

                                      Trace adds a TRACE route to the default Mux. See the documentation for web.Mux for more information about what types this function accepts.

                                      func Use

                                      func Use(middleware web.MiddlewareType)

                                        Use appends the given middleware to the default Mux's middleware stack. See the documentation for web.Mux.Use for more information.

                                        Types

                                        This section is empty.

                                        Directories

                                        Path Synopsis
                                        Package bind provides a convenient way to bind to sockets.
                                        Package bind provides a convenient way to bind to sockets.
                                        Command example is a sample application built with Goji.
                                        Command example is a sample application built with Goji.
                                        Package graceful implements graceful shutdown for HTTP servers by closing idle connections after receiving a signal.
                                        Package graceful implements graceful shutdown for HTTP servers by closing idle connections after receiving a signal.
                                        listener
                                        Package listener provides a way to incorporate graceful shutdown to any net.Listener.
                                        Package listener provides a way to incorporate graceful shutdown to any net.Listener.
                                        web
                                        Package web provides a fast and flexible middleware stack and mux.
                                        Package web provides a fast and flexible middleware stack and mux.
                                        middleware
                                        Package middleware provides several standard middleware implementations.
                                        Package middleware provides several standard middleware implementations.
                                        mutil
                                        Package mutil contains various functions that are helpful when writing http middleware.
                                        Package mutil contains various functions that are helpful when writing http middleware.