Categorygithub.com/rcrowley/go-tigertonic
modulepackage
0.0.0-20170420123839-fe6b9f080eb7
Repository: https://github.com/rcrowley/go-tigertonic.git
Documentation: pkg.go.dev

# README

Tiger Tonic

Build Status

A Go framework for building JSON web services inspired by Dropwizard. If HTML is your game, this will hurt a little.

Like the Go language itself, Tiger Tonic strives to keep features orthogonal. It defers what it can to the Go standard library and a few other packages.

Documentation

Articles and talks

Reference

http://godoc.org/github.com/rcrowley/go-tigertonic

Community

Synopsis

tigertonic.TrieServeMux

HTTP routing in the Go standard library is pretty anemic. Enter tigertonic.TrieServeMux. It accepts an HTTP method, a URL pattern, and an http.Handler or an http.HandlerFunc. Components in the URL pattern wrapped in curly braces - { and } - are wildcards: their values (which don't cross slashes) are added to the URL as u.Query().Get("name").

HandleNamespace is like Handle but additionally strips the namespace from the URL, making API versioning, multitenant services, and relative links easier to manage. This is roughly equivalent to http.ServeMux's behavior.

tigertonic.HostServeMux

Use tigertonic.HostServeMux to serve multiple domain names from the same net.Listener.

tigertonic.Marshaled

Wrap a function in tigertonic.Marshaled to turn it into an http.Handler. The function signature must be something like this or tigertonic.Marshaled will panic:

func myHandler(*url.URL, http.Header, *MyRequest) (int, http.Header, *MyResponse, error)

Request bodies will be unmarshaled into a MyRequest struct and response bodies will be marshaled from MyResponse structs.

Should you need to respond with an error, the tigertonic.HTTPEquivError interface is implemented by tigertonic.BadRequest (and so on for every other HTTP response status) that can be wrapped around any error:

func myHandler(*url.URL, http.Header, *MyRequest) (int, http.Header, *MyResponse, error) {
    return 0, nil, nil, tigertonic.BadRequest{errors.New("Bad Request")}
}

Alternatively, you can return a valid status as the first output parameter and an error as the last; that status will be used in the error response.

If the return type of a tigertonic.Marshaled handler interface implements the io.Reader interface the stream will be written directly to the requestor. A Content-Type header is required to be specified in the response headers and the Accept header for these particular requests can be anything.

Additionally, if the return type of the tigertonic.Marshaled handler implements the io.Closer interface the stream will be automatically closed after it is flushed to the requestor.

tigertonic.Logged, tigertonic.JSONLogged, and tigertonic.ApacheLogged

Wrap an http.Handler in tigertonic.Logged to have the request and response headers and bodies logged to standard output. The second argument is an optional func(string) string called as requests and responses are logged to give the caller the opportunity to redact sensitive information from log entries.

Wrap an http.Handler in tigertonic.JSONLogged to have the request and response headers and bodies logged to standard output as JSON suitable for sending to ElasticSearch, Flume, Logstash, and so on. The JSON will be prefixed with @json: . The second argument is an optional func(string) string called as requests and responses are logged to give the caller the opportunity to redact sensitive information from log entries.

Wrap an http.Handler in tigertonic.ApacheLogged to have the request and response logged in the more traditional Apache combined log format.

tigertonic.Counted and tigertonic.Timed

Wrap an http.Handler in tigertonic.Counted or tigertonic.Timed to have the request counted or timed with go-metrics.

tigertonic.CountedByStatus and tigertonic.CountedByStatusXX

Wrap an http.Handler in tigertonic.CountedByStatus or tigertonic.CountedByStatusXX to have the response counted with go-metrics with a metrics.Counter for each HTTP status code or family of status codes (1xx, 2xx, and so on).

tigertonic.First

Call tigertonic.First with a variadic slice of http.Handlers. It will call ServeHTTP on each in succession until the first one that calls w.WriteHeader.

tigertonic.If

tigertonic.If expresses the most common use of tigertonic.First more naturally. Call tigertonic.If with a func(*http.Request) (http.Header, error) and an http.Handler. It will conditionally call the handler unless the function returns an error. In that case, the error is used to create a response.

tigertonic.PostProcessed and tigertonic.TeeResponseWriter

tigertonic.PostProcessed uses a tigertonic.TeeResponseWriter to record the response and call a func(*http.Request, *http.Response) after the response is written to the client to allow post-processing requests and responses.

tigertonic.HTTPBasicAuth

Wrap an http.Handler in tigertonic.HTTPBasicAuth, providing a map[string]string of authorized usernames to passwords, to require the request include a valid Authorization header.

tigertonic.CORSHandler and tigertonic.CORSBuilder

Wrap an http.Handler in tigertonic.CORSHandler (using CORSBuilder.Build()) to inject CORS-related headers. Currently only Origin-related headers (used for cross-origin browser requests) are supported.

tigertonic.Configure

Call tigertonic.Configure to read and unmarshal a JSON configuration file into a configuration structure of your own design. This is mere convenience and what you do with it after is up to you.

tigertonic.WithContext and tigertonic.Context

Wrap an http.Handler and a zero value of any non-interface type in tigertonic.WithContext to enable per-request context. Each request may call tigertonic.Context with the *http.Request in progress to get a pointer to the context which is of the type passed to tigertonic.WithContext.

tigertonic.Version

Respond with a version string that may be set at compile-time.

Usage

Install dependencies:

sh bootstrap.sh

Then define your service. The working example may be a more convenient place to start.

Requests that have bodies have types. JSON is deserialized by adding tigertonic.Marshaled to your routes.

type MyRequest struct {
	ID     string      `json:"id"`
	Stuff  interface{} `json:"stuff"`
}

Responses, too, have types. JSON is serialized by adding tigertonic.Marshaled to your routes.

type MyResponse struct {
	ID     string      `json:"id"`
	Stuff  interface{} `json:"stuff"`
}

Routes are just functions with a particular signature. You control the request and response types.

func myHandler(u *url.URL, h http.Header, *MyRequest) (int, http.Header, *MyResponse, error) {
    return http.StatusOK, nil, &MyResponse{"ID", "STUFF"}, nil
}

Wire it all up in main.main!

mux := tigertonic.NewTrieServeMux()
mux.Handle("POST", "/stuff", tigertonic.Timed(tigertonic.Marshaled(myHandler), "myHandler", nil))
tigertonic.NewServer(":8000", tigertonic.Logged(mux, nil)).ListenAndServe()

Ready for more? See the full example which includes all of these handlers plus an example of how to use tigertonic.Server to stop gracefully. Build it with go build, run it with ./example, and test it out:

curl -H"Host: example.com" -sv "http://127.0.0.1:8000/1.0/stuff/ID"
curl -H"Host: example.com" -X"POST" -d'{"id":"ID","stuff":"STUFF"}' -sv "http://127.0.0.1:8000/1.0/stuff"
curl -H"Host: example.com" -X"POST" -d'{"id":"ID","stuff":"STUFF"}' -sv "http://127.0.0.1:8000/1.0/stuff/ID"
curl -H"Host: example.com" -sv "http://127.0.0.1:8000/1.0/forbidden"

WTF?

Dropwizard was named after http://gunshowcomic.com/316 so Tiger Tonic was named after http://gunshowcomic.com/338.

If Tiger Tonic isn't your cup of tea, perhaps one of these fine tools suits you:

# Packages

No description provided by the author
Package mocking makes testing Tiger Tonic services easier.

# Functions

ApacheLogged returns an http.Handler that logs requests and responses in the Apache combined log format.
Cached returns an http.Handler that sets appropriate Cache headers on the outgoing response and passes requests to a wrapped http.Handler.
Configure delegates reading and unmarshaling of the given configuration file to the appropriate function from ConfigExt.
ConfigureJSON reads the given configuration file and unmarshals the JSON found into the given configuration structure.
Context returns the request context as an interface{} given a pointer to the request itself.
Counted returns an http.Handler that passes requests to an underlying http.Handler and then counts the request via go-metrics.
CountedByStatus returns an http.Handler that passes requests to an underlying http.Handler and then counts the response by its HTTP status code via go-metrics.
CountedByStatusXX returns an http.Handler that passes requests to an underlying http.Handler and then counts the response by the first digit of its HTTP status code via go-metrics.
First returns an http.Handler that, for each handler in its slice of handlers, calls ServeHTTP until the first one that calls w.WriteHeader.
HTTPBasicAuth returns an http.Handler that conditionally calls another http.Handler if the request includes an Authorization header with a username and password that appear in the map of credentials.
HTTPBasicAuthFunc returns an http.Handler that conditionally calls another http.Handler if the request includes an Authorization header with a username and password that produce a nil error when passed to the given function.
If returns an http.Handler that conditionally calls another http.Handler unless the given function returns an error.
JSONLogged returns an http.Handler that logs requests and responses in a parse-able json line.
Logged returns an http.Handler that logs requests and responses, complete with paths, statuses, headers, and bodies.
Marshaled returns an http.Handler that implements its ServeHTTP method by calling the given function, the signature of which must be func(*url.URL, http.Header, *Request) (int, http.Header, *Response) where Request and Response may be any struct type of your choosing.
No description provided by the author
NewHostServeMux makes a new HostServeMux.
Return a new HTTPEquivError whose StatusCode method returns the given status code.
No description provided by the author
NewRequestID returns a new 16-character random RequestID.
NewServer returns an http.Server with better defaults and built-in graceful stop.
NewTeeHeaderResponseWriter constructs a new TeeHeaderResponseWriter that writes responses through another http.ResponseWriter and records the response status and headers for post-processing.
NewTeeResponseWriter constructs a new TeeResponseWriter that writes responses through another http.ResponseWriter and records the response status, headers, and body for post-processing.
NewTLSServer returns an http.Server with better defaults configured to use the certificate and private key files.
NewTrieServeMux makes a new TrieServeMux.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Timed returns an http.Handler that starts a timer, passes requests to an underlying http.Handler, stops the timer, and updates the timer via go-metrics.
WithContext wraps an http.Handler and associates a new context object of the same type as the second parameter with each request it handles.

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

No description provided by the author
ResponseErrorWriter is a handler for outputting errors to the http.ResponseWriter.
SnakeCaseHTTPEquivErrors being true will cause tigertonic.HTTPEquivError error responses to be written as (for example) "not_found" rather than "tigertonic.NotFound".

# Structs

No description provided by the author
ApacheLogger is an http.Handler that logs requests and responses in the Apache combined log format.
No description provided by the author
No description provided by the author
CacheControl is an http.Handler that sets cache headers.
These set the relevant headers in the response per http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html.
No description provided by the author
Conn is just a net.Conn that accounts for itself so the listener can be stopped gracefully.
ContextHandler is an http.Handler that associates a context object of any type with each request it handles.
No description provided by the author
CORSBuilder facilitates the application of the same set of CORS rules to a number of endpoints.
CORSHandler wraps an http.Handler while correctly handling CORS related functionality, such as Origin headers.
Counter is an http.Handler that counts requests via go-metrics.
CounterByStatus is an http.Handler that counts responses by their HTTP status code via go-metrics.
CounterByStatusXX is an http.Handler that counts responses by the first digit of their HTTP status code via go-metrics.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
JSONLogged is an http.Handler that logs requests and responses in a parse-able json line.
No description provided by the author
Listener is just a net.Listener that accounts for connections it accepts so it can be stopped gracefully.
Marshaler is an http.Handler that unmarshals JSON input, handles the request via a function, and marshals JSON output.
No description provided by the author
MethodNotAllowedHandler responds 405 to every request with an Allow header and possibly with a JSON body.
No description provided by the author
MultilineLogger is an http.Handler that logs requests and responses, complete with paths, statuses, headers, and bodies.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
NotFoundHandler responds 404 to every request, possibly with a JSON body.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Server is an http.Server with better defaults and built-in graceful stop.
No description provided by the author
No description provided by the author
No description provided by the author
TeeHeaderResponseWriter is an http.ResponseWriter that both writes and records the response status and headers for post-processing.
TeeResponseWriter is an http.ResponseWriter that both writes and records the response status, headers, and body for post-processing.
No description provided by the author
Timer is an http.Handler that counts requests via go-metrics.
TrieServeMux is an HTTP request multiplexer that implements http.Handler with an API similar to http.ServeMux.
No description provided by the author
No description provided by the author
No description provided by the author

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

Err is an alias for the built-in error type so that it can be publicly exported when embedding.
FirstHandler is an http.Handler that, for each handler in its slice of handlers, calls ServeHTTP until the first one that calls w.WriteHeader.
HostServeMux is an HTTP request multiplexer that implements http.Handler with an API similar to http.ServeMux.
MarshalerError is the response body for some 500 responses and panics when a handler function is not suitable.
A Redactor is a function that takes and returns a string.
A unique RequestID is given to each request and is included with each line of each log entry.
A RequestIDCreator is a function that takes a request and returns a unique RequestID for it.
Version is an http.Handler that responds to every request with itself in plain text.