siesta

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2021 License: MIT Imports: 12 Imported by: 15

README

siesta

GoDoc build codecov

Siesta is a framework for writing composable HTTP handlers in Go. It supports typed URL parameters, middleware chains, and context passing.

Getting started

Siesta offers a Service type, which is a collection of middleware chains and handlers rooted at a base URI. There is no distinction between a middleware function and a handler function; they are all considered to be handlers and have access to the same arguments.

Siesta accepts many types of handlers. Refer to the GoDoc documentation for Service.Route for more information.

Here is the simple program in the examples directory. It demonstrates the use of a Service, routing, middleware, and a Context.

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/VividCortex/siesta"
)

func main() {
	// Create a new Service rooted at "/"
	service := siesta.NewService("/")

	// Route accepts normal http.Handlers.
	// The arguments are the method, path, description,
	// and the handler.
	service.Route("GET", "/", "Sends 'Hello, world!'",
		func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, world!")
	})

	// Let's create some simple "middleware."
	// This handler will accept a Context argument and will add the current
	// time to it.
	timestamper := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set("start", time.Now())
	}

	// This is the handler that will actually send data back to the client.
	// It also takes a Context argument so it can get the timestamp from the
	// previous handler.
	timeHandler := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		start := c.Get("start").(time.Time)
		delta := time.Now().Sub(start)
		fmt.Fprintf(w, "That took %v.\n", delta)
	}

	// We can compose these handlers together.
	timeHandlers := siesta.Compose(timestamper, timeHandler)

	// Finally, we'll add the new handler we created using composition to a new route.
	service.Route("GET", "/time", "Sends how long it took to send a message", timeHandlers)

	// service is an http.Handler, so we can pass it directly to ListenAndServe.
	log.Fatal(http.ListenAndServe(":8080", service))
}

Siesta also provides utilities to manage URL parameters similar to the flag package. Refer to the params example for a demonstration.

Contributing

We only accept pull requests for minor fixes or improvements. This includes:

  • Small bug fixes
  • Typos
  • Documentation or comments

Please open issues to discuss new features. Pull requests for new features will be rejected, so we recommend forking the repository and making changes in your fork for your use case.

License

Siesta is licensed under the MIT license. The router, which is adapted from httprouter, is licensed separately.

Documentation

Index

Constants

View Source
const UsageContextKey = nullByteStr + "usage"

UsageContextKey is a special context key to get the route usage information within a handler.

Variables

View Source
var ErrUnsupportedHandler = errors.New("siesta: unsupported handler")

Functions

This section is empty.

Types

type Context

type Context interface {
	Set(string, interface{})
	Get(string) interface{}
}

Context is a context interface that gets passed to each ContextHandler.

type ContextHandler

type ContextHandler func(Context, http.ResponseWriter, *http.Request, func())

ContextHandler is a siesta handler.

func Compose

func Compose(stack ...interface{}) ContextHandler

Compose composes multiple ContextHandlers into a single ContextHandler.

func ToContextHandler

func ToContextHandler(f interface{}) ContextHandler

ToContextHandler transforms f into a ContextHandler. f must be a function with one of the following signatures:

func(http.ResponseWriter, *http.Request)
func(http.ResponseWriter, *http.Request, func())
func(Context, http.ResponseWriter, *http.Request)
func(Context, http.ResponseWriter, *http.Request, func())

func (ContextHandler) ServeHTTP

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

func (ContextHandler) ServeHTTPInContext

func (h ContextHandler) ServeHTTPInContext(c Context, w http.ResponseWriter, r *http.Request)

type EmptyContext

type EmptyContext struct{}

EmptyContext is a blank context.

func (EmptyContext) Get

func (c EmptyContext) Get(key string) interface{}

func (EmptyContext) Set

func (c EmptyContext) Set(key string, value interface{})

type Params

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

Params represents a set of URL parameters from a request's query string. The interface is similar to a flag.FlagSet, but a) there is no usage string, b) there are no custom Var()s, and c) there are SliceXXX types. Sliced types support two ways of generating a multi-valued parameter: setting the parameter multiple times, and using a comma-delimited string. This adds the limitation that you can't have a value with a comma if in a Sliced type. Under the covers, Params uses flag.FlagSet.

func (*Params) Bool

func (rp *Params) Bool(name string, value bool, usage string) *bool

Bool defines a bool param with specified name and default value. The return value is the address of a bool variable that stores the value of the param.

func (*Params) Duration

func (rp *Params) Duration(name string, value time.Duration, usage string) *time.Duration

Duration defines a time.Duration param with specified name and default value. The return value is the address of a time.Duration variable that stores the value of the param.

func (*Params) Float64

func (rp *Params) Float64(name string, value float64, usage string) *float64

Float64 defines a float64 param with specified name and default value. The return value is the address of a float64 variable that stores the value of the param.

func (*Params) Int

func (rp *Params) Int(name string, value int, usage string) *int

Int defines an int param with specified name and default value. The return value is the address of an int variable that stores the value of the param.

func (*Params) Int64

func (rp *Params) Int64(name string, value int64, usage string) *int64

Int64 defines an int64 param with specified name and default value. The return value is the address of an int64 variable that stores the value of the param.

func (*Params) Parse

func (rp *Params) Parse(args url.Values) error

Parse parses URL parameters from a http.Request.URL.Query(), which is a url.Values, which is just a map[string][string].

func (*Params) SliceBool

func (rp *Params) SliceBool(name string, value bool, usage string) *SBool

SliceBool defines a multi-value bool param with specified name and default value. The return value is the address of a SBool variable that stores the values of the param.

func (*Params) SliceDuration

func (rp *Params) SliceDuration(name string, value time.Duration, usage string) *SDuration

SliceDuration defines a multi-value time.Duration param with specified name and default value. The return value is the address of a SDuration variable that stores the values of the param.

func (*Params) SliceFloat64

func (rp *Params) SliceFloat64(name string, value float64, usage string) *SFloat64

SliceFloat64 defines a multi-value float64 param with specified name and default value. The return value is the address of a SFloat64 variable that stores the values of the param.

func (*Params) SliceInt

func (rp *Params) SliceInt(name string, value int, usage string) *SInt

SliceInt defines a multi-value int param with specified name and default value. The return value is the address of a SInt variable that stores the values of the param.

func (*Params) SliceInt64

func (rp *Params) SliceInt64(name string, value int64, usage string) *SInt64

SliceInt64 defines a multi-value int64 param with specified name and default value. The return value is the address of a SInt64 variable that stores the values of the param.

func (*Params) SliceString

func (rp *Params) SliceString(name string, value string, usage string) *SString

SliceString defines a multi-value string param with specified name and default value. The return value is the address of a SString variable that stores the values of the param.

func (*Params) SliceUint

func (rp *Params) SliceUint(name string, value uint, usage string) *SUint

SliceUint defines a multi-value uint param with specified name and default value. The return value is the address of a SUint variable that stores the values of the param.

func (*Params) SliceUint64

func (rp *Params) SliceUint64(name string, value uint64, usage string) *SUint64

SliceUint64 defines a multi-value uint64 param with specified name and default value. The return value is the address of a SUint64 variable that stores the values of the param.

func (*Params) String

func (rp *Params) String(name string, value string, usage string) *string

String defines a string param with specified name and default value. The return value is the address of a string variable that stores the value of the param.

func (*Params) Uint

func (rp *Params) Uint(name string, value uint, usage string) *uint

Uint defines a uint param with specified name and default value. The return value is the address of a uint variable that stores the value of the param.

func (*Params) Uint64

func (rp *Params) Uint64(name string, value uint64, usage string) *uint64

Uint64 defines a uint64 param with specified name and default value. The return value is the address of a uint64 variable that stores the value of the param.

func (*Params) Usage

func (rp *Params) Usage() map[string][3]string

Usage returns a map keyed on parameter names. The map values are an array of name, type, and usage information for each parameter.

type SBool

type SBool []bool

SBool is a slice of bool.

func (*SBool) Set

func (s *SBool) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SBool) String

func (s *SBool) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SDuration

type SDuration []time.Duration

SDuration is a slice of time.Duration.

func (*SDuration) Set

func (s *SDuration) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SDuration) String

func (s *SDuration) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SFloat64

type SFloat64 []float64

SFloat64 is a slice of float64.

func (*SFloat64) Set

func (s *SFloat64) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SFloat64) String

func (s *SFloat64) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SInt

type SInt []int

SInt is a slice of int.

func (*SInt) Set

func (s *SInt) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SInt) String

func (s *SInt) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SInt64

type SInt64 []int64

SInt64 is a slice of int64.

func (*SInt64) Set

func (s *SInt64) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SInt64) String

func (s *SInt64) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SString

type SString []string

SString is a slice of string.

func (*SString) Set

func (s *SString) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SString) String

func (s *SString) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SUint

type SUint []uint

SUint is a slice of uint.

func (*SUint) Set

func (s *SUint) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SUint) String

func (s *SUint) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type SUint64

type SUint64 []uint64

SUint64 is a slice of uint64.

func (*SUint64) Set

func (s *SUint64) Set(value string) error

Set is the method to set the param value, part of the flag.Value interface. Set's argument is a string to be parsed to set the param. It's a comma-separated list, so we split it.

func (*SUint64) String

func (s *SUint64) String() string

String is the method to format the param's value, part of the flag.Value interface. The String method's output will be used in diagnostics.

type Service

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

A Service is a container for routes with a common base URI. It also has two middleware chains, named "pre" and "post".

The "pre" chain is run before the main handler. The first handler in the "pre" chain is guaranteed to run, but execution may quit anywhere else in the chain.

If the "pre" chain executes completely, the main handler is executed. It is skipped otherwise.

The "post" chain runs after the main handler, whether it is skipped or not. The first handler in the "post" chain is guaranteed to run, but execution may quit anywhere else in the chain if the quit function is called.

func NewService

func NewService(baseURI string) *Service

NewService returns a new Service with the given base URI or panics if the base URI has already been registered.

func (*Service) AddPost

func (s *Service) AddPost(f interface{})

AddPost adds f to the end of the "post" chain. It panics if f cannot be converted to a ContextHandler (see Service.Route).

func (*Service) AddPre

func (s *Service) AddPre(f interface{})

AddPre adds f to the end of the "pre" chain. It panics if f cannot be converted to a ContextHandler (see Service.Route).

func (*Service) DisableTrimSlash

func (s *Service) DisableTrimSlash()

DisableTrimSlash disables the removal of trailing slashes before route matching.

func (*Service) Register

func (s *Service) Register()

Register registers s by adding it as a handler to the DefaultServeMux in the net/http package.

func (*Service) Route

func (s *Service) Route(verb, uriPath, usage string, f interface{})

Route adds a new route to the Service. f must be a function with one of the following signatures:

func(http.ResponseWriter, *http.Request)
func(http.ResponseWriter, *http.Request, func())
func(Context, http.ResponseWriter, *http.Request)
func(Context, http.ResponseWriter, *http.Request, func())

Note that Context is an interface type defined in this package. The last argument is a function which is called to signal the quitting of the current execution sequence.

func (*Service) ServeHTTP

func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request)

Service satisfies the http.Handler interface.

func (*Service) ServeHTTPInContext

func (s *Service) ServeHTTPInContext(c Context, w http.ResponseWriter, r *http.Request)

ServeHTTPInContext serves an HTTP request within the Context c. A Service will run through both of its internal chains, quitting when requested.

func (*Service) SetNotFound

func (s *Service) SetNotFound(f interface{})

SetNotFound sets the handler for all paths that do not match any existing routes. It accepts the same function signatures that Route does with the addition of `nil`.

func (*Service) SetPostExecutionFunc

func (s *Service) SetPostExecutionFunc(f func(c Context, r *http.Request, panicValue interface{}))

SetPostExecutionFunc sets a function that is executed at the end of every request. panicValue will be non-nil if a value was recovered after a panic.

type SiestaContext

type SiestaContext map[string]interface{}

SiestaContext is a concrete implementation of the siesta.Context interface. Typically this will be created by the siesta framework itself upon each request. However creating your own SiestaContext might be useful for testing to isolate the behavior of a single handler.

func NewSiestaContext

func NewSiestaContext() SiestaContext

func (SiestaContext) Get

func (c SiestaContext) Get(key string) interface{}

func (SiestaContext) Set

func (c SiestaContext) Set(key string, value interface{})

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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