Documentation ¶
Overview ¶
Package bowtie provides a Web middleware for Go apps.
More information at https://github.com/mtabini/go-bowtie
For a quick start, check out the examples at http://godoc.org/github.com/mtabini/go-bowtie/quick
Index ¶
- type Context
- type ContextFactory
- type ContextInstance
- type ContextKey
- type Error
- type ErrorInstance
- func (e *ErrorInstance) CaptureStackTrace() Error
- func (e *ErrorInstance) Data() interface{}
- func (e *ErrorInstance) Error() string
- func (e *ErrorInstance) MarshalJSON() ([]byte, error)
- func (e *ErrorInstance) Message() string
- func (e *ErrorInstance) PrivateRepresentation() map[string]interface{}
- func (e *ErrorInstance) SetData(data interface{})
- func (e *ErrorInstance) StackTrace() []StackFrame
- func (e *ErrorInstance) StatusCode() int
- func (e *ErrorInstance) String() string
- type Middleware
- type MiddlewareProvider
- type Request
- type ResponseWriter
- type ResponseWriterFactory
- type ResponseWriterInstance
- func (r *ResponseWriterInstance) AddError(err error)
- func (r *ResponseWriterInstance) Errors() []Error
- func (r *ResponseWriterInstance) Status() int
- func (r *ResponseWriterInstance) Write(p []byte) (int, error)
- func (r *ResponseWriterInstance) WriteHeader(status int)
- func (r *ResponseWriterInstance) WriteJSON(data interface{}) (int, error)
- func (r *ResponseWriterInstance) WriteJSONOrError(data interface{}, err error) (int, error)
- func (r *ResponseWriterInstance) WriteOrError(p []byte, err error) (int, error)
- func (r *ResponseWriterInstance) WriteString(s string) (int, error)
- func (r *ResponseWriterInstance) WriteStringOrError(s string, err error) (int, error)
- func (r *ResponseWriterInstance) Written() bool
- type Server
- func (s *Server) AddContextFactory(value ContextFactory)
- func (s *Server) AddMiddleware(f Middleware)
- func (s *Server) AddMiddlewareProvider(p MiddlewareProvider)
- func (s *Server) NewContext(r *http.Request, w http.ResponseWriter) Context
- func (s *Server) Run(c Context)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- type StackFrame
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Context ¶
type Context interface { // Get returns a property set into the context Get(ContextKey) interface{} // Set sets a new property into the context Set(ContextKey, interface{}) // Request returns the request object associated with this request Request() *Request // Response returns the response writer associated with this request Response() ResponseWriter // GetRunningTime returns the amount of time during which this request has been running GetRunningTime() time.Duration }
Interface Context represents a server's context, which provides information used by the middleware. The basic context deals primarily with providing an interface to the request and response
func NewContext ¶
func NewContext(r *http.Request, w http.ResponseWriter) Context
NewContext is a ContextFactory that creates a basic context. You will probably want to create your own context and context factory that extends the basic context for your uses
type ContextFactory ¶
type ContextFactory func(context Context)
ContextFactory is a function that processes a context. Your application (and each middleware) can provide its own factory when the server is created, thus allowing you to set new values into the context as needed
type ContextInstance ¶
type ContextInstance struct {
// contains filtered or unexported fields
}
Struct ContextInstance is a concrete implementation of the base server context. Your application can safely incorporate it into its own structs to extend the functionality provided by Bowtie
func (*ContextInstance) Get ¶
func (c *ContextInstance) Get(key ContextKey) interface{}
func (*ContextInstance) GetRunningTime ¶
func (c *ContextInstance) GetRunningTime() time.Duration
GetRunningTime returns the amount of time during which this request has been running
func (*ContextInstance) Request ¶
func (c *ContextInstance) Request() *Request
Request returns the request associated with the context
func (*ContextInstance) Response ¶
func (c *ContextInstance) Response() ResponseWriter
Response returns the response writer assocaited with the context
func (*ContextInstance) Set ¶
func (c *ContextInstance) Set(key ContextKey, value interface{})
type ContextKey ¶
type ContextKey int64
func GenerateContextKey ¶
func GenerateContextKey() ContextKey
type Error ¶
type Error interface { error fmt.Stringer json.Marshaler // StatusCode return the error's status code StatusCode() int // Message returns the error's message Message() string // Data returns the error's associated data Data() interface{} // SetData sets the error's associated data SetData(interface{}) // PrivateRepresentation a private representation of the error. Useful for logging. PrivateRepresentation() map[string]interface{} // GetStackTrace returns the stack trace associated with this error, if any StackTrace() []StackFrame // RecordStackTrace captures a stack track and return the error instance CaptureStackTrace() Error }
Interface Error represents a Bowtie error, which extends the standard error interface to provide additional Web-friendly functionality.
Instances of Error must be able to provide both a public and private representation; the latter may include sensitive information like stack traces and private messages, while the former can be safely outputted to an end user.
func NewError ¶
NewError builds a new Error instance; the `format` and `arguments` parameters work as in `fmt.Sprintf()`
func NewErrorWithError ¶
NewErrorFromError builds a new Error instance starting from a regular Go error (or something that can be cast to it). If an instance of Error is passed to it, the function returns a copy thereof (and not the original), but _not_ of the associated data, which may be copied by reference.
If the error
type ErrorInstance ¶
type ErrorInstance struct {
// contains filtered or unexported fields
}
Struct ErrorInstance incorporates an error and associates it with an HTTP status code (assumed to be 500 if not present. Arbitrary data can also be added to the error for logging purposes, as can a stack trace.
The ErrorInstance struct is smart enough that, when asked for serialization either through error's Error() method or by JSON marshalling, it does not leak any sensitive information if the StatusCode is >= 500 (which indicates a server error).
For status codes that indicate user errors ([400-499]), the struct allows public consumers to see the actual message that was provided at initialization time.
func (*ErrorInstance) CaptureStackTrace ¶
func (e *ErrorInstance) CaptureStackTrace() Error
func (*ErrorInstance) Data ¶
func (e *ErrorInstance) Data() interface{}
Returns the data associated with e
func (*ErrorInstance) Error ¶
func (e *ErrorInstance) Error() string
Satisfy the error, fmt.Stringer, and json.Marshaler interfaces
func (*ErrorInstance) MarshalJSON ¶
func (e *ErrorInstance) MarshalJSON() ([]byte, error)
func (*ErrorInstance) Message ¶
func (e *ErrorInstance) Message() string
Returns the message associated with e
func (*ErrorInstance) PrivateRepresentation ¶
func (e *ErrorInstance) PrivateRepresentation() map[string]interface{}
Returns a private representation of e
func (*ErrorInstance) SetData ¶
func (e *ErrorInstance) SetData(data interface{})
Sets the data associated with e
func (*ErrorInstance) StackTrace ¶
func (e *ErrorInstance) StackTrace() []StackFrame
func (*ErrorInstance) StatusCode ¶
func (e *ErrorInstance) StatusCode() int
Returns the status code associated with e
func (*ErrorInstance) String ¶
func (e *ErrorInstance) String() string
type Middleware ¶
type Middleware func(c Context, next func())
Middleware is a function that encapsulate a Bowtie middleware. It receives an execution context and a next function it can optionally call to delay its own execution until the end of the request (useful for logging, error handling, etc.)
type MiddlewareProvider ¶
type MiddlewareProvider interface { Middleware() Middleware ContextFactory() ContextFactory }
Interface MiddleProvider can be implemented by structs that want to offer both a middleware and a context factory. They can be installed onto a server by calling AddMiddlewareProvider()
type Request ¶
Struct Request adds a few convenience functions to `http.Request`.
func NewRequest ¶
NewRequest creates a new request instance. This is called transparently for you at the time the server receives a request
func (*Request) JSONBody ¶
JSONBody attempts to unmarshal JSON out of the request's body, and returns a map if successful, or an error if not.
func (*Request) ReadJSONBody ¶
ReadJSONBody attempts to unmarshal JSON from the request's body into a destination of your choosing.
func (*Request) StringBody ¶
StringBody returns the request's body as a string
type ResponseWriter ¶
type ResponseWriter interface { http.ResponseWriter // Add error safely adds a new error to the context, converting it to bowtie.Error if appropriate AddError(err error) // Errors returns an array that contains any error assigned to the response writer Errors() []Error // Status returns the HTTP status code of the writer. You can set this by using `WriteHeader()` Status() int // Written returns true if any data (including a status code) has been written to the writer's // output stream Written() bool // WriteOrError checks if `err` is not nil, in which case it adds it to the context's error // list and returns. If `err` is nil, `p` is written to the output stream instead. This is a // convenient way of dealing with functions that return (data, error) tuples inside a middleware WriteOrError(p []byte, err error) (int, error) // WriteString is a convenience method that outputs a string WriteString(s string) (int, error) // WriteStringOrError is a convenience method that outputs a string or adds an error to the writer. // It works like `WriteOrError`, but takes string instead of a byte array WriteStringOrError(s string, err error) (int, error) // WriteJSON writes data in JSON format to the output stream. The output Content-Type header // is also automatically set to `application/json` WriteJSON(data interface{}) (int, error) // WriteJSONOrError checks if `err` is not nil, in which case it adds it to the context's error // list and returns. If `err` is nil, `data` is serialized to JSON and written to the output // stream instead; the Content-Type of the response is also set to `application/json` automatically. // This is a convenient way of dealing with functions that return (data, error) tuples inside // a middleware WriteJSONOrError(data interface{}, err error) (int, error) }
Interface ResponseWriter extends the functionality provided by `http.ResponseWriter`, mainly by adding a few convenience methods for writing strings and JSON data and dealing with errors.
You can provide your own extended ResponseWriter by creating a custom ResponseWriterFactory function and setting it to the ResponseWriterFactory property of your server.
func NewResponseWriter ¶
func NewResponseWriter(w http.ResponseWriter) ResponseWriter
type ResponseWriterFactory ¶
type ResponseWriterFactory func(w http.ResponseWriter) ResponseWriter
type ResponseWriterInstance ¶
type ResponseWriterInstance struct { http.ResponseWriter // contains filtered or unexported fields }
func (*ResponseWriterInstance) AddError ¶
func (r *ResponseWriterInstance) AddError(err error)
Add error safely adds a new error to the context, converting it to bowtie.Error if appropriate
func (*ResponseWriterInstance) Errors ¶
func (r *ResponseWriterInstance) Errors() []Error
Errors returns an array that contains any error assigned to the response writer
func (*ResponseWriterInstance) Status ¶
func (r *ResponseWriterInstance) Status() int
Status returns the HTTP status code of the writer. You can set this by using `WriteHeader()`
func (*ResponseWriterInstance) Write ¶
func (r *ResponseWriterInstance) Write(p []byte) (int, error)
Write implements io.Writer and outputs data to the HTTP stream
func (*ResponseWriterInstance) WriteHeader ¶
func (r *ResponseWriterInstance) WriteHeader(status int)
WriteHeader writes a status header
func (*ResponseWriterInstance) WriteJSON ¶
func (r *ResponseWriterInstance) WriteJSON(data interface{}) (int, error)
WriteJSON writes data in JSON format to the output stream. The output Content-Type header is also automatically set to `application/json`
func (*ResponseWriterInstance) WriteJSONOrError ¶
func (r *ResponseWriterInstance) WriteJSONOrError(data interface{}, err error) (int, error)
WriteJSONOrError checks if `err` is not nil, in which case it adds it to the context's error list and returns. If `err` is nil, `data` is serialized to JSON and written to the output stream instead; the Content-Type of the response is also set to `application/json` automatically. This is a convenient way of dealing with functions that return (data, error) tuples inside a middleware
func (*ResponseWriterInstance) WriteOrError ¶
func (r *ResponseWriterInstance) WriteOrError(p []byte, err error) (int, error)
WriteOrError checks if `err` is not nil, in which case it adds it to the context's error list and returns. If `err` is nil, `p` is written to the output stream instead. This is a convenient way of dealing with functions that return (data, error) tuples inside a middleware
func (*ResponseWriterInstance) WriteString ¶
func (r *ResponseWriterInstance) WriteString(s string) (int, error)
WriteString is a convenience method that outputs a string
func (*ResponseWriterInstance) WriteStringOrError ¶
func (r *ResponseWriterInstance) WriteStringOrError(s string, err error) (int, error)
WriteStringOrError is a convenience method that outputs a string or adds an error to the writer. It works like `WriteOrError`, but takes string instead of a byte array
func (*ResponseWriterInstance) Written ¶
func (r *ResponseWriterInstance) Written() bool
Written returns true if any data (including a status code) has been written to the writer's output stream
type Server ¶
type Server struct { ResponseWriterFactory ResponseWriterFactory // contains filtered or unexported fields }
Struct Server is a Bowtie server. It provides a handler compatible with http.ListenAndServe that creates a context and executes any attached middleware.
Example (Middleware) ¶
package main import ( "net/http" ) // Struct MyContext extends Bowtie's context and adds more features to it type MyContext struct { Context DBURL string } // Struct MyMiddlewareProvider satisfies the MiddlewareProvider interface // and provides both a middleware and a context factory type MyMiddlewareProvider struct { DBURL string } // ContextFactory, when added to a server, “wraps” our context around an // existing context. At execution time, the middleware can then cast // the context that the server passes to it to MyContext and take // advantage of its functionality. func (m *MyMiddlewareProvider) ContextFactory() ContextFactory { return func(previous Context) Context { // Return an instance of our context that encapsulates the previous // context created for the server return &MyContext{ Context: previous, DBURL: m.DBURL, } } } // A middleware is simply a function that takes a context, which it can // use to manipulate the current HTTP request, and a next function that // can be called to delay the middleware's execution until after all // other middlewares have run. func (m *MyMiddlewareProvider) Middleware() Middleware { return func(c Context, next func()) { // Cast the context to our context and get the DB URL myC := c.(*MyContext) // Output the URL to the client c.Response().WriteString(myC.DBURL) } } func main() { // Create a new Bowtie server s := NewServer() // Register our new middleware provider. This adds our context factory // to it, and injects our middleware into its execution queue. s.AddMiddlewareProvider(&MyMiddlewareProvider{DBURL: "db:/my/database"}) // Server can be used directly with http.ListenAndServe http.ListenAndServe(":8000", s) }
Output:
func (*Server) AddContextFactory ¶
func (s *Server) AddContextFactory(value ContextFactory)
SetContextFactory changes the context factory used by the server. This allows you to create your own Context structs and use them inside your apps.
func (*Server) AddMiddleware ¶
func (s *Server) AddMiddleware(f Middleware)
AddMiddleware adds a new middleware handler. Handlers are executed in the order in which they are added to the server
func (*Server) AddMiddlewareProvider ¶
func (s *Server) AddMiddlewareProvider(p MiddlewareProvider)
AddMiddlewareProvider registers a new middleware provider
func (*Server) NewContext ¶
NewContext creates a new basic server context. You should not need to call this except for testing purposes. Instead, you should extend the server context with your struct and provide a context factory to the server
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package middleware contains several middlewares for bowtie.
|
Package middleware contains several middlewares for bowtie. |
Package quick provides the easiest way to stand up a Bowtie server.
|
Package quick provides the easiest way to stand up a Bowtie server. |