goji

package
v0.0.0-...-52c5e1e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2016 License: MIT, MIT Imports: 5 Imported by: 0

README

Goji

Goji is a HTTP request multiplexer, similar to net/http.ServeMux. It compares incoming requests to a list of registered Patterns, and dispatches to the Handler that corresponds to the first matching Pattern. Goji also supports Middleware (composable shared functionality applied to every request) and uses the de facto standard x/net/context to store request-scoped values.

Quick Start

package main

import (
        "fmt"
        "net/http"

        "goji.io"
        "goji.io/pat"
        "golang.org/x/net/context"
)

func hello(ctx context.Context, w http.ResponseWriter, r *http.Request) {
        name := pat.Param(ctx, "name")
        fmt.Fprintf(w, "Hello, %s!", name)
}

func main() {
        mux := goji.NewMux()
        mux.HandleFuncC(pat.Get("/hello/:name"), hello)

        http.ListenAndServe("localhost:8000", mux)
}

Please refer to Goji's GoDoc Documentation for a full API reference.

Stability

As of this writing (late November 2015), this version of Goji is still very new, and during this initial experimental stage it offers no API stability guarantees. After the API has had a little time to bake, Goji expects to adhere strictly to the Go project's compatibility guidelines, guaranteeing to never break compatibility with existing code.

We expect to be able to make such a guarantee by early 2016. Although we reserve the right to do so, there are no breaking API changes planned until that point, and we are unlikely to accept any such breaking changes.

Community / Contributing

Goji maintains a mailing list, gojiberries, where you should feel welcome to ask questions about the project (no matter how simple!), to announce projects or libraries built on top of Goji, or to talk about Goji more generally. Goji's author (Carl Jackson) also loves to hear from users directly at his personal email address, which is available on his GitHub profile page.

Contributions to Goji are welcome, however please be advised that due to Goji's stability guarantees interface changes are unlikely to be accepted.

All interactions in the Goji community will be held to the high standard of the broader Go community's Code of Conduct.

Documentation

Overview

Package goji is a minimalistic and flexible HTTP request multiplexer.

Goji itself has very few features: it is first and foremost a standard set of interfaces for writing web applications. Several subpackages are distributed with Goji to provide standard production-ready implementations of several of the interfaces, however users are also encouraged to implement the interfaces on their own, especially if their needs are unusual.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Handler

type Handler interface {
	ServeHTTPC(context.Context, http.ResponseWriter, *http.Request)
}

Handler is a context-aware variant of net/http.Handler. It has the same semantics as http.Handler, except that a request-scoped context is additionally passed to the handler function.

type HandlerFunc

type HandlerFunc func(context.Context, http.ResponseWriter, *http.Request)

HandlerFunc is a context-aware variant of net/http.HandlerFunc. It has the same semantics as http.Handler, except that a request-scoped context is additionally passed to the function.

HandlerFunc implements both the Handler and http.Handler interfaces.

func (HandlerFunc) ServeHTTP

func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements net/http.Handler. It calls the underlying function with a context of context.TODO in order to ease the conversion of non-context-aware Handlers to context-aware ones using static analysis.

func (HandlerFunc) ServeHTTPC

func (h HandlerFunc) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request)

ServeHTTPC implements Handler.

type Mux

type Mux struct {
	// contains filtered or unexported fields
}

Mux is a HTTP multiplexer / router similar to net/http.ServeMux.

Muxes multiplex traffic between many Handlers by selecting the first applicable Pattern. They then call a common middleware stack, finally passing control to the selected Handler. See the documentation on the Handle function for more information about how routing is performed, the documentation on the Pattern type for more information about request matching, and the documentation for the Use method for more about middleware.

Muxes cannot be configured concurrently from multiple goroutines, nor can they be configured concurrently with requests.

func NewMux

func NewMux() *Mux

NewMux returns a new Mux with no configured middleware or routes.

A common pattern is to organize your application similarly to how you structure your URLs. For instance, a photo-sharing site might have URLs that start with "/users/" and URLs that start with "/albums/"; such a site might have three Muxes: one to manage the URL hierarchy for users, one to manage albums, and a third top-level Mux to select between the other two.

func (*Mux) Handle

func (m *Mux) Handle(p Pattern, h http.Handler)

Handle adds a new route to the Mux. Requests that match the given Pattern will be dispatched to the given http.Handler. If the http.Handler also supports Handler, that interface will be used instead.

Routing is performed in the order in which routes are added: the first route with a matching Pattern will be used. In particular, Goji guarantees that routing is performed in a manner that is indistinguishable from the following algorithm:

// Assume routes is a slice that every call to Handle appends to
for route := range routes {
	// For performance, Patterns can opt out of this call to Match.
	// See the documentation for Pattern for more.
	if ctx2 := route.pattern.Match(ctx, r); ctx2 != nil {
		route.handler.ServeHTTPC(ctx2, w, r)
		break
	}
}

It is not safe to concurrently register routes from multiple goroutines.

func (*Mux) HandleC

func (m *Mux) HandleC(p Pattern, h Handler)

HandleC adds a new context-aware route to the Mux. See the documentation for Handle for more information about the semantics of routing.

It is not safe to concurrently register routes from multiple goroutines.

func (*Mux) HandleFunc

func (m *Mux) HandleFunc(p Pattern, h func(http.ResponseWriter, *http.Request))

HandleFunc adds a new route to the Mux. It is equivalent to calling Handle on a handler wrapped with http.HandlerFunc, and is provided only for convenience.

func (*Mux) HandleFuncC

func (m *Mux) HandleFuncC(p Pattern, h func(context.Context, http.ResponseWriter, *http.Request))

HandleFuncC adds a new context-aware route to the Mux. It is equivalent to calling HandleC on a handler wrapped with HandlerFunc, and is provided for convenience.

func (*Mux) ServeHTTP

func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements net/http.Handler. It uses context.TODO as the root context in order to ease the conversion of non-context-aware Handlers to context-aware ones using static analysis.

Users who know that their mux sits at the top of the request hierarchy should consider creating a small helper http.Handler that calls this Mux's ServeHTTPC function with context.Background.

func (*Mux) ServeHTTPC

func (m *Mux) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request)

ServeHTTPC implements Handler.

func (*Mux) Use

func (m *Mux) Use(middleware func(http.Handler) http.Handler)

Use appends a middleware to the Mux's middleware stack.

Middleware are composable pieces of functionality that augment Handlers. Common examples of middleware include request loggers, authentication checkers, and metrics gatherers.

Middleware are evaluated in the reverse order in which they were added, but the resulting Handlers execute in "normal" order (i.e., the Handler returned by the first Middleware to be added gets called first).

For instance, given middleware A, B, and C, added in that order, Goji's behavior will look something like this:

augmentedHandler := A(B(C(yourHandler)))
augmentedHandler.ServeHTTPC(ctx, w, r)

Assuming each of A, B, and C look something like this:

func A(inner goji.Handler) goji.Handler {
	log.Print("A: called")
	mw := func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		log.Print("A: before")
		inner.ServeHTTPC(ctx, w, r)
		log.Print("A: after")
	}
	return goji.HandlerFunc(mw)
}

we'd expect to see the following in the log:

C: called
B: called
A: called
---
A: before
B: before
C: before
yourHandler: called
C: after
B: after
A: after

Note that augmentedHandler may be called many times. Put another way, you will see many invocations of the portion of the log below the divider, and perhaps only see the portion above the divider a single time. Also note that as an implementation detail, net/http-style middleware will be called once per request, even though the Goji-style middleware around them might only ever be called a single time.

Middleware in Goji is called after routing has been performed. Therefore it is possible to examine any routing information placed into the context by Patterns, or to view or modify the Handler that will be routed to.

The http.Handler returned by the given middleware must be safe for concurrent use by multiple goroutines. It is not safe to concurrently register middleware from multiple goroutines.

func (*Mux) UseC

func (m *Mux) UseC(middleware func(Handler) Handler)

UseC appends a context-aware middleware to the Mux's middleware stack. See the documentation for Use for more information about the semantics of middleware.

The Handler returned by the given middleware must be safe for concurrent use by multiple goroutines. It is not safe to concurrently register middleware from multiple goroutines.

type Pattern

type Pattern interface {
	// Match examines the request and request context to determine if the
	// request is a match. If so, it returns a non-nil context.Context
	// derived from the input Context (or perhaps the input Context
	// unchanged). The returned context may be used to store request-scoped
	// data, such as variables extracted from the URL.
	//
	// Match must not mutate the passed request.
	Match(context.Context, *http.Request) context.Context
}

Pattern determines whether or not a given request matches some criteria. Goji users looking for a concrete type that implements this interface should consider Goji's "pat" sub-package, which implements a small domain specific language for HTTP routing.

Most patterns match on a relatively small portion of incoming requests, most commonly the HTTP method and the URL's RawPath. As an optimization, Goji can elide calls to your Pattern for requests it knows cannot match. Pattern authors who wish to take advantage of this functionality (and in some cases an asymptotic performance improvement) can augment their Pattern implementations with methods with any of the following signatures:

// HTTPMethods returns a set of HTTP methods that all requests that this
// Pattern matches must be in, or nil if it's not possible to determine
// which HTTP methods might be matched.
HTTPMethods() map[string]struct{}

// PathPrefix returns a string which all RawPaths that match this
// Pattern must contain as a prefix.
PathPrefix() string

The presence or lack of these performance improvements should be viewed as an implementation detail and are not part of Goji's API compatibility guarantee. It is the responsibility of Pattern authors to ensure that their Match function (which is part of the API compatibility guarantee) always returns correct results, even if optimizations are not performed.

All operations on Patterns must be safe for concurrent use by multiple goroutines.

Directories

Path Synopsis
Package internal is a private package that allows Goji to expose a less confusing interface to its users.
Package internal is a private package that allows Goji to expose a less confusing interface to its users.
Package middleware contains utilities for Goji Middleware authors.
Package middleware contains utilities for Goji Middleware authors.
Package pat is a URL-matching domain-specific language for Goji.
Package pat is a URL-matching domain-specific language for Goji.
Package pattern contains utilities for Goji Pattern authors.
Package pattern contains utilities for Goji Pattern authors.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL