verto

package module
v0.0.0-...-d7376be Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2016 License: MIT Imports: 14 Imported by: 0

README

Verto

Build Status GoDoc

Examples
Benchmarks

Verto is a simple REST framework that provides routing, error handling, response handling,
logging, and middleware chaining.

Basic Usage
  // Initialize Verto
  v := verto.New()
  
  // Register a route
  v.Add("GET", "/", func(c *verto.Context) (interface{}, error) {
    fmt.Fprintf(c.Response, "Hello, World!")
  })
  
  // Run Verto
  v.Run()
Resource Function

Verto accepts a custom ResourceFunction:

  type ResourceFunc(c *Context) (interface{}, error) func

The function takes in a Verto Context struct. The Context contains
a map of injections that we will discuss later. The resource function
returns an interface{} and optionally an error. If the call to the resource was successful,
a nil error should be returned. The default Verto instance will be able to handle any errors
or interface{} return values but in a very basic way. It is recommended for the user to bring
a custom response and error handler to Verto.

Verto will also happily take http.Handler as a routing endpoint.

Routing

Verto offers simple routing. Endpoints are registered using the Add and AddHandker
methods. The parameters are the method to be matched, the path to be matched, and the endpoint
handler. Add takes a verto.ResourceFunc as an endpoint and AddHandler takes a
normal http.Handler.

  // Basic routing example
  endpoint1 := verto.ResourceFunc(c *verto.Context) (interface{}, error) {
    fmt.Fprintf(c.Response, "Hello, World!")
  })
  endpoint2 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
  })
  
  v.Add("GET", "/path/to/1", endpoint1)
  v.Add("POST", "/path/to/1", endpoint1)
  
  v.AddHandler("PUT", "/path/to/2", endpoint2)

Verto also includes the option for named parameters in the path. Named parameters can be more strictly defined using regular expressions. Named parameters will be injected into
r.FormValue() and, if the endpoint is a ResourceFunc, will be retrievable through the
Context utility functions.

  // Named routing example
  endpoint1 := verto.ResourceFunc(c *verto.Context) (interface{}, error) {
    fmt.Fprintf(c.Response, c.Get("param"))
  })
  endpoint2 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, r.FormValue("param"))
  })
  
  // Named parameters are denoted by { }
  v.Add("GET", "/path/to/{param}", endpoint1)
  v.Add("POST", "/path/to/{param}", endpoint1)
  
  // Apply a regex check to the param by use of : followed by
  // the regex.
  v.AddHandler("PUT", "/path/to/{param: ^[0-9]+$}", endpoint2)
Path redirection

If a path contains extraneous symbols like extra /'s or .'s (barring trailing /'s), Verto will automatically clean the path and send a redirect response to the cleaned path. By default, Verto will not attempt to redirect paths with (without) trailing slashes if the other exists. Calling SetStrict(false) on a Verto instance lets Verto know that you want it to redirect trailing slashes.

Middleware Chaining

Verto provides the option to chain middleware both globally and per route. Middleware must come in one of 3 forms:

  • mux.PluginFunc type PluginFunc(w http.ResponseWriter, r *http.Request, next http.Handler) func
  • verto.PluginFunc type PluginFunc(c *Context, next http.Handler) func
  • http.Handler

If the middleware comes in the form of an http.Handler, next is automatically called.

   // Example middleware usage
   v := verto.New()

   // Simple plugins
   mw1 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
     fmt.Println("Hello, World 1!")
   })
   mw2 := mux.PluginFunc(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
     fmt.Println("Hello, World 2!")
     next(w, r)
   })
   mw3 := verto.PluginFunc(func(c *verto.Context, next http.Handler) {
     fmt.Println("Hello, World 3!")
     next(w, r)
   })
   
   // Register global plugins: These will run for every single
   // request. Middleware is served first come - first serve.
   v.UseHandler(mw1)
   v.UsePluginHandler(mw2)
   v.Use(mw3)
   
   // Register route
   v.Add("GET", "/", func(c *verto.Context) (interface{}, error) {
     fmt.Fprintf(c.Response, "Finished.")
   })
   
   v.Run()

Middleware can also be chained per route

  // Register route and chain middle ware. These middleware
  // will only be run for GET requests on /.
  v.Add("GET", "/", func(c *verto.Context) (interface{}, error) {
    ...
  }).UseHandler(mw1).UsePluginHandler(mw2).Use(mw3)
Groups

Verto provides the ability to create route groups.

// Create a group
g := v.Group("GET", "/path/path2/path3")

// Add endpoint handlers to a route group. The full path
// for the handler will be /path/path2/path3/handler. 
g.Add("GET", "/handler", http.HandlerFunc(
  func(w http.ResponseWriter, http.Request) {
    fmt.Fprintf(w, "Hello!")
  },
))

// Middleware can be chained per route group. Middleware
// will be run for all subgroups and handlers under the parent
// group.
g.Use(mux.PluginFunc(
  func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
    fmt.Fprintf(w, "World!")
  },
))

// Create subgroups attached to a group. The resulting subgroup
// path will be /path/path2/path3/path4.
sub := g.Group("/path4")

Creating a group when there exists other groups/endpoint handlers that share a path prefix with the new group will cause those groups/endpoints to be subsumed under the new group. When creating groups, all wildcard segments are treated as equal. Thus, groups/endpoints subsumed under a new group with a wildcard segment in the shared prefix will use the new group's wildcard segment as key instead of their old segments. Attempting to create an already existing group returns the existing group.

Context

Context is the custom parameter used for Verto's ResourceFuncs.
It contains the original http.ResponseWriter and *http.Request
as well as a reference to a logger and injections.
Context also provides a set of utility functions for dealing with parameter
setting and retrieval.

  type Context struct {
    // The original ResponseWriter and Request
    Request  *http.Request
    Response http.ResponseWriter
    
    // Logger
    Logger Logger
    
    // Injections
    Injections *Injections
  }
  
  // Retrieves the first string value associated with the key. 
  func (c *Context) Get(key string) string { }
  
  // Performs exactly like Get() but returns all values associated with the key.
  func (c *Context) GetMulti(key string) []string { }
  
  // Performs exactly like Get() but converts the value to a bool if possible.
  // Throws an error if the conversion fails
  func (c *Context) GetBool(key string) (bool, error) { }
  
  // Does the same thing as GetBool() but converts to a float64 instead.
  func (c *Context) GetFloat64(key string) (float64, error) { }
  
  // Does the same thing as GetBool() but converts to an int64 instead.
  func (c *Context) GetInt64(key string) (int64, error) { }
  
  // Sets the value associated with key.
  func (c *Context) Set(key, value string) { }
  
  // Associated multiple values with the key.
  func (c *Context) SetMulti(key string, values []string) { }
  
  // Associates a boolean value with the key. Throws an error if there was a problem formatting value.
  func (c *Context) SetBool(key string, value bool) error { }
  
  // Associates a float64 value with the key. Throws an error if there was a problem formatting value.
  func (c *Context) SetFloat64(key string, value float64) error { }
  
  // Associates a int64 value with the key. Throws an error if there was a problem formatting value.
  func (c *Context) SetInt64(key string, value int64) error { }
  
  // The first call to Get or Set functions will attempt to parse the request query string
  // and body for parameters so that they are available from the Get functions as well.
  // Any errors encountered parsing can be retrieved using the ParseErrors function
  func (c *Context) ParseErrors() error { }
Response Handler

Verto allows the user to define his own response handling function.
The handler must be of the form:

  type ResponseHandler interface {
    Handle(response interface{}, c *Context)
  }

Verto also defines a ResponseFunc to wrap functions so that
they implement ResponseHandler. A default handler is provided
and used if no custom handler is provided. It is recommended that
the user brings his own handler as the default just attempts to
write response as is.

  // Custom response handler example
  handler := verto.ResponseFunc(func(response interface{}, c *verto.Context) {
    // Attempt to marshal response as JSON before writing it
    body, _ := json.Marshal(response)
    fmt.Fprintf(c.Response, body)
  })
  
  v.RegisterResponseHandler(handler)
Error Handler

Like response handling, Verto allows the user to define his own error handler. The handler must be of the form:

  type ErrorHandler interface {
    Handle(err error, c *Context)
  }

Verto also defines an ErrorFunc to wrap functions so that they implement
ErrorHandler. A default handler is provided but it is recommended that
the user brings his own handler. The default just responds with a 500 Internal Server Error.

  // Custom error handler example
  handler := verto.ErrorFunc(func(err error, c *Context) {
    fmt.Fprintf(c.Response, "Custom error response!")
  })
  
  v.RegisterErrorHandler(handler)
Injections

Injections are anything from the outside world you need passed to an endpoint
handler. A thread-local copy of the Injections struct is provided to each request in order to support per-request lazy initialization of injections

NOTE: All Injections functions ARE thread safe.

  // Injection example
  
  // Inject using the Injections.Set() function. The first parameter
  // is the key used to access then injection from within
  // any handlers or plugins that implement verto.PluginFunc.
  v.Injections.Set("key", "value")
  
  // Lazily inject objects that have a high initialization cost
  // The lifetime can be set to SINGLETON so that the object is only
  // initialized once on the first call to Get/TryGet, or REQUEST so
  // that the factory function is called per first call of Get/TryGet
  // per request. The factory function provided to the lazy function
  // takes in an interface ReadOnlyInjections that allows lazy injections
  // to be instantiated based on other injected objects. ReadOnlyInjections
  // only supports the Get/TryGet functions but otherwise works the same
  // as Injections
  v.Injections.Lazy("cache-client", 
    func(r verto.ReadOnlyInjections) interface{} {
      return interface{} // example placeholder
    }, verto.REQUEST)
  
  // Inject anything like slices or structs
  sl := make([]int64, 5)
  st := &struct{
    Value int64,
  }{}
  v.Injections.Set("slice", sl)
  v.Injections.Set("struct", st)
  
  // Retrieve values with Get()
  st2 := v.Injections.Get("struct")
  
  // TryGet() lets you check if the value exists
  st3, exists := v.Injections.TryGet("struct")
  
  // Delete() removes an injection.
  v.Injections.Delete("slice")
  
  // Clear clears all injections
  v.Injections.Clear()

Injections are useful for things intricate loggers, analytics,
and caching.

Logging

Verto provides a default logger implementation but allows custom loggers that implement the following interface:

type Logger interface {
  // The following functions print messages
  // at various levels to any open log files and subscribers
  Info(v ...interface{})
  Debug(v ...interface{})
  Warn(v ...interface{})
  Error(v ...interface{})
  Fatal(v ...interface{})
  Panic(v ...interface{})
  
  // The following functions print formatted messages
  // at various levels to any open log files and subscribers
  Infof(format string, v ...interface{})
  Debugf(format string, v ...interface{})
  Warnf(format string, v ...interface{}) 
  Errorf(format string, v ...interface{})
  Fatalf(format string, v ...interface{})
  Panicf(format string, v ...interface{})
  
  // Print a message to open log files and subscribers
  Print(v ...interface{})
  // Print a formatted message to open log files and subscribers
  Printf(format string, v ...interface{})
  
  // Close should dispose of any resources held by the logger
  // (e.g. files, channels, etc.)
  Close()
}

Documentation

Overview

Package verto is a simple REST framework. It is plug n' play and includes it's own path multiplexer, error handler, and response handler. It is recommended to bring your own error handling and response handling. Verto provides users the option to use middleware globally or per route. The Verto multiplexer is not substitutable

Index

Constants

This section is empty.

Variables

View Source
var ErrContextNotInitialized = errors.New("context not initialized")

ErrContextNotInitialized is generated by Context Get/Set utility functions if the Context was not properly initialized. Contexts passed to request handlers and plugins are guaranteed to be properly initialized.

View Source
var ErrStopped = errors.New("listener stopped")

ErrStopped gets returned by stoppable listener when a stop signal is sent to the listener.

Functions

func DefaultErrorFunc

func DefaultErrorFunc(err error, c *Context)

DefaultErrorFunc is the default error handling function for Verto. DefaultErrorFunc sends a 500 response and writes the error's error message to the response body.

func DefaultResponseFunc

func DefaultResponseFunc(response interface{}, c *Context)

DefaultResponseFunc is the default response handling function for Verto. DefaultResponseFunc sends a 200 response and attempts to write the response directly to the http response body.

func GetIP

func GetIP(r *http.Request) string

GetIP retrieves the ip address of the requester. GetIp recognizes the "X-Forwarded-For" header.

func JSONResponseFunc

func JSONResponseFunc(response interface{}, c *Context)

JSONResponseFunc attempts to write the returned response to the ResponseWriter as JSON. JSONResponseFunc Will return an HTTP 500 error if the marshalling failed

func XMLResponseFunc

func XMLResponseFunc(response interface{}, c *Context)

XMLResponseFunc attempts to write the returned response to the ResponseWriter as XML. XMLResponseFunc will return an HTTP 500 error if the marshalling failed.

Types

type Context

type Context struct {
	// The original ResponseWriter
	Response http.ResponseWriter

	// The original *http.Request
	Request *http.Request

	// Factory functions for retrieving injections
	// Since Contexts are created per-request, this function
	// allows each context to receive a request-unique
	// Injections instance allowing for per-request lazy
	// initializations
	Injections func() Injections

	// If Verto has a registered Logger, it can be
	// accessed here.
	Logger Logger
	// contains filtered or unexported fields
}

Context contains useful state information for request handling. Inside Context is the original http.ResponseWriter and *http.Request as well as access to a Logger and Injections. Context is thread-safe.

func NewContext

func NewContext(w http.ResponseWriter, r *http.Request, i func() Injections, l Logger) *Context

NewContext initializes a new Context with the passed in response, request, injections, and logger

func (*Context) Get

func (c *Context) Get(key string) string

Get retrieves the request parameter associated with key. If there was an error retrieving the parameter, the error is stored and retrievable by the ParseError call.

func (*Context) GetBool

func (c *Context) GetBool(key string) (bool, error)

GetBool retrieves the value associated with key as a bool or returns an error if the conversion failed

func (*Context) GetFloat64

func (c *Context) GetFloat64(key string) (float64, error)

GetFloat64 retrieves the value associated with key as a float64 or returns an error if the conversion failed

func (*Context) GetInt64

func (c *Context) GetInt64(key string) (int64, error)

GetInt64 retrieves the value associated with key as an int64 or returns an error if the conversion failed

func (*Context) GetMulti

func (c *Context) GetMulti(key string) []string

GetMulti returns the a slice containing all relevant parameters tied to key. If there was an error retrieving the parameters, the error is stored and retrievable by the ParseError call

func (*Context) ParseError

func (c *Context) ParseError() error

ParseError returns the error encountered while parsing the HTTP request for parameter values or nil if no error was encountered

func (*Context) Set

func (c *Context) Set(key, value string)

Set associates a request parameter value with key.

func (*Context) SetBool

func (c *Context) SetBool(key string, value bool)

SetBool converts a boolean value to a string and associates it with a key in the context

func (*Context) SetFloat64

func (c *Context) SetFloat64(key string, value float64, fmt byte, prec int)

SetFloat64 converts a float64 to a string and associates it with a key in the context

func (*Context) SetInt64

func (c *Context) SetInt64(key string, value int64)

SetInt64 converts an int64 to a (base 10 representation) string and associates it with a key in the context

func (*Context) SetMulti

func (c *Context) SetMulti(key string, values []string)

SetMulti associates multiple parameter values with key.

type DefaultLogger

type DefaultLogger struct {

	// DropTimeout is the duration before a message is dropped
	// when attempting to pipe messages to a subscriber
	DropTimeout time.Duration
	// contains filtered or unexported fields
}

DefaultLogger is the Verto default implementation of the Logger interface. This logger is thread-safe.

func NewLogger

func NewLogger() *DefaultLogger

NewLogger returns a newly initialized VertoLogger instance.

func (*DefaultLogger) AddFile

func (dl *DefaultLogger) AddFile(f *os.File)

AddFile registers an open file for logging. The caller should take care to make sure the file is valid for writing. The logger will handle closing the file when the logger is closed.

func (*DefaultLogger) AddFilePath

func (dl *DefaultLogger) AddFilePath(path string) error

AddFilePath attempts to open the file at path as append-only and will begin writing messages to the file or return an error if an error occured opening up the file.

func (*DefaultLogger) AddSubscriber

func (dl *DefaultLogger) AddSubscriber(key string) <-chan string

AddSubscriber registers a channel with the logger and returns the channel. Any messages written to the logger will be piped out to the returned channel.

NOTE: If a previous subscriber with the same key exists, it will be OVERWRITTEN.

func (*DefaultLogger) Close

func (dl *DefaultLogger) Close()

Close attempts to close all opened files attached to VertoLogger. Any errors encountered while closing files are captured in the errors map

func (*DefaultLogger) Debug

func (dl *DefaultLogger) Debug(v ...interface{})

Debug prints a debug level message to all subscribers and open log files.

func (*DefaultLogger) Debugf

func (dl *DefaultLogger) Debugf(format string, v ...interface{})

Debugf prints a formatted debug level message to all subscribers and open log files.

func (*DefaultLogger) Dropped

func (dl *DefaultLogger) Dropped(key string) []string

Dropped returns a slice of strings representing any dropped log messages due to timeout sends to the subscriber described by key.

func (*DefaultLogger) Error

func (dl *DefaultLogger) Error(v ...interface{})

Error prints an error level message to all subscribers and open log files.

func (*DefaultLogger) Errorf

func (dl *DefaultLogger) Errorf(format string, v ...interface{})

Errorf prints a formatted error level message to all subscribers and open log files.

func (*DefaultLogger) Errors

func (dl *DefaultLogger) Errors() map[string][]error

Errors returns a slice of all errors that occured while writing to files

func (*DefaultLogger) Fatal

func (dl *DefaultLogger) Fatal(v ...interface{})

Fatal prints a fatal level message to all subscribers and open log files and then calls os.Exit

func (*DefaultLogger) Fatalf

func (dl *DefaultLogger) Fatalf(format string, v ...interface{})

Fatalf prints a formatted fatal level message to all subscribers and open log files and then calls os.Exit

func (*DefaultLogger) Info

func (dl *DefaultLogger) Info(v ...interface{})

Info prints an info level message to all subscribers and open log files.

func (*DefaultLogger) Infof

func (dl *DefaultLogger) Infof(format string, v ...interface{})

Infof prints a formatted info level message to all subscribers and open log files.

func (*DefaultLogger) Panic

func (dl *DefaultLogger) Panic(v ...interface{})

Panic prints a panic level message to all subscribers and open log files and then panics

func (*DefaultLogger) Panicf

func (dl *DefaultLogger) Panicf(format string, v ...interface{})

Panicf prints a formatted panic level message to all subscribers and open log files and then panics

func (*DefaultLogger) Print

func (dl *DefaultLogger) Print(v ...interface{})

Print prints a message to all subscribers and open log files.

func (*DefaultLogger) Printf

func (dl *DefaultLogger) Printf(format string, v ...interface{})

Printf prints a formatted message to all subscribers and open log files.

func (*DefaultLogger) Warn

func (dl *DefaultLogger) Warn(v ...interface{})

Warn prints a warn level message to all subscribers and open log files.

func (*DefaultLogger) Warnf

func (dl *DefaultLogger) Warnf(format string, v ...interface{})

Warnf prints a formatted warn level message to all subscribers and open log files.

type Endpoint

type Endpoint struct {
	mux.Endpoint
	// contains filtered or unexported fields
}

Endpoint is an object returned by add route functions that allow the addition of plugins to be executed on the added route. Endpoint is able to handle plain http.Handlers, mux.PluginHandlers, and verto.Plugins as middleware plugins. Endpoint is a wrapper around mux.Endpoint

func (*Endpoint) Use

func (ep *Endpoint) Use(plugin Plugin) *Endpoint

Use adds a Plugin onto the chain of plugins to be executed when the route represented by the Endpoint is requested. The Plugin will have it's context provided by the Verto instance that generated the Endpoint

func (*Endpoint) UseHandler

func (ep *Endpoint) UseHandler(handler http.Handler) *Endpoint

UseHandler adds an http.handler onto the chain of plugins to be executed when the route represented by the Endpoint is requested. http.Handler plugins will always call the next-in-line plugin if one exists

func (*Endpoint) UsePluginHandler

func (ep *Endpoint) UsePluginHandler(handler mux.PluginHandler) *Endpoint

UsePluginHandler adds a mux.PluginHandler onto the chain of plugins to be executed when the route represented by the Endpoint is requested.

type ErrorFunc

type ErrorFunc func(err error, c *Context)

ErrorFunc wraps functions so that they implement ErrorHandler

func (ErrorFunc) Handle

func (erf ErrorFunc) Handle(err error, c *Context)

Handle calls the function wrapped by ErrorFunc.

type ErrorHandler

type ErrorHandler interface {

	// Handle handles the error. Context is guaranteed to be
	// populated if ErrorHandler is registed through Verto.
	Handle(err error, c *Context)
}

ErrorHandler is the Verto-specific interface for error handlers. A default ErrorHandler is provided with Verto but it is recommended to bring your own ErrorHandler.

type FactoryFn

type FactoryFn func(w http.ResponseWriter, r *http.Request, i ReadOnlyInjections) interface{}

FactoryFn represents a factory function for lazy initialization of injectable objects. FactoryFn takes in a ReadOnlyInjections interface to allow ReadOnly access to the outer Injections container as well as a http.ResponseWriter and http.Request that is populated if the function is called per-request. If the function is set with a SINGLETON LifeTime, w and r will be nil

type Group

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

Group represents a group of routes in Verto. Routes are generally grouped by a shared path prefix but can also be grouped by method as well. Group allows the addition of plugins to be run whenever a path within the group is requested

func (*Group) Add

func (g *Group) Add(path string, rf ResourceFunc) *Endpoint

Add registers a ResourceFunc at the path under Group. The resulting route will have a full path equivalent to the passed in path appended onto the Group's path prefix. An Endpoint representing the added route is returned. If the path already exists, this function will overwrite the old handler with the passed in ResourceFunc.

func (*Group) AddHandler

func (g *Group) AddHandler(path string, handler http.Handler) *Endpoint

AddHandler registers an http.Handler as the handler for the passed in path. AddHandler behaves exactly the same as Add except that it takes in an http.Handler instead of a ResourceFunc

func (*Group) Group

func (g *Group) Group(path string) *Group

Group registers a sub-Group under the current Group at the passed in path. The new Group's full path is equivalent to the passed in path appended to the current Group's path prefix. Any existing endpoints and groups who might fall under the new Group (e.g. path prefix == new Group's path) will be subsumed by the new Group. If a sub-Group exists with a path that is a path prefix of the would-be new Group, the new Group is added under the sub-Group instead. If a sub-Group already exists at the given path, the existing Group is not overwritten and is returned. Otherwise the newly created Group is returned.

func (*Group) Use

func (g *Group) Use(plugin Plugin) *Group

Use adds a Plugin to be executed for all paths and sub-Groups under the current group.

func (*Group) UseHandler

func (g *Group) UseHandler(handler http.Handler) *Group

UseHandler adds an http.Handler as a plugin to be executed for all paths and sub-Groups under the current Group. http.Handler plugins will always call the next-in-line plugin if one exists

func (*Group) UsePluginHandler

func (g *Group) UsePluginHandler(handler mux.PluginHandler) *Group

UsePluginHandler adds a mux.PluginHandler as a plugin to be executed for all paths and sub-Groups under the current group.

type HttpHandler

type HttpHandler struct {
	*Verto
}

HttpHandler is a wrapper around Verto such that it can run as an http.handler

func (*HttpHandler) ServeHTTP

func (handler *HttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves requests directly to Verto's muxer.

type IClone

type IClone struct {
	*IContainer
	// contains filtered or unexported fields
}

IClone is a cloned version of the IContainer and should have a 1-1 relation with an http.Request. IClone maintains a request-specific map for evaluating per-request factory functions

func (*IClone) Clear

func (i *IClone) Clear()

Clear will clear all key value associations in the global injections container as well as in the thread-specific map. Clear does not affect any other IClone instances.

func (*IClone) Delete

func (i *IClone) Delete(key string)

Delete will delete the key value association in the global injections container as well as in the thread-specific map. Delete does not affect any other IClone instances

func (*IClone) Get

func (i *IClone) Get(key string) interface{}

Get calls TryGet on the IClone and disregards the boolean value indicating success

func (*IClone) TryGet

func (i *IClone) TryGet(key string) (interface{}, bool)

TryGet attempts to retrieve the desired value first from the global injection store and then from the thread-specific map. If need be, lazy factory functions are evaluated first. IClone's TryGet will, unlike the TryGet for the IContainer, evaluate per-request factory functions. Each IClone will execute the per-request function only once in its lifetime. The per-request scoping comes from the IContainer spawning an IClone per incoming http.Request

type IContainer

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

IContainer is a master container for Injections and should only be instantiated once with NewContainer. The container should be cloned for each request and the request should use the clone instead of the master container. IContainer implements the Injections interface but, generally speaking, the Get and TryGet functions should only be called from requests on cloned containers.

func NewContainer

func NewContainer() *IContainer

NewContainer returns a pointer to a newly initiated Injections Container.

func (*IContainer) Clear

func (i *IContainer) Clear()

Clear clears out all key-value (or factory) associations for this container. This function will not delete per-request evaluated values for existing clones.

func (*IContainer) Clone

func (i *IContainer) Clone(w http.ResponseWriter, r *http.Request) *IClone

Clone returns a thread-specific clone of the IContainer.

func (*IContainer) Delete

func (i *IContainer) Delete(key string)

Delete deletes the value or factory function associated with the key for this container. This function will not delete per-request evaluated values for existing clones.

func (*IContainer) Get

func (i *IContainer) Get(key string) interface{}

Get calls TryGet and disposes of the returned bool. Thus it is possible to get nil values for a key if the key does not exist or is a lazy function with a per-request LifeTime

func (*IContainer) Lazy

func (i *IContainer) Lazy(key string, fn FactoryFn, lifetime LifeTime)

Lazy associates a factory function with the passed in LifeTime with the passed in key for this container and all its clones. The factory function will be evaluated upon retrieval through Get or TryGet. Per-request LifeTime functions can only be evaluated by clones.

func (*IContainer) Set

func (i *IContainer) Set(key string, value interface{})

Set associates a value with a key for this container and all its clones. Values always have a singleton LifeTime.

func (*IContainer) TryGet

func (i *IContainer) TryGet(key string) (interface{}, bool)

TryGet attempts to retrieve the value associated with the passed in key and returns the value and a success boolean. If the key does not exist or is associated with a per-request LifeTime lazy function, a nil interface and false will be returned. Otherwise, the associated value and true is returned. This function will evaluate lazy functions with a singleton LifeTime

type Injections

type Injections interface {
	// Get returns the value associated with key in Injections
	// or nil if the key does not exist. Get will evaluate any
	// factory functions associated with key if they have not
	// already been evaluated
	Get(key string) interface{}

	// TryGet returns the value associated with key in Injections
	// and a boolean indicating if the retrieval was successful or not.
	// If TryGet is successful and the key is associated with a un-evaluated
	// factory function, the factory function will be evaluated
	TryGet(key string) (interface{}, bool)

	// Set associates a key with a value in Injections.
	Set(key string, value interface{})

	// Lazy associates a factory function with a key that will lazily initialize
	// an object using the factory function when the key is retrieved.
	Lazy(key string, fn FactoryFn, lifetime LifeTime)

	// Delete deletes a key-value association in Injections.
	Delete(key string)

	// Clear deletes all key-value associations in Injections.
	Clear()
}

Injections is a thread-safe map of keys to data objects. Injections is used by Verto to allow outside dependencies to be injected by the user into request handlers and plugins.

type LifeTime

type LifeTime int64

LifeTime represents the possible life time lengths for a lazily injected value

const (
	// SINGLETON is a lifetime for lazy injections
	// that are instantiated only once
	SINGLETON LifeTime = iota

	// REQUEST is a lifetime for lazy injections
	// that should be re-initialized per request
	REQUEST
)

type Logger

type Logger interface {
	Info(v ...interface{})
	Debug(v ...interface{})
	Warn(v ...interface{})
	Error(v ...interface{})
	Fatal(v ...interface{})
	Panic(v ...interface{})

	Infof(format string, v ...interface{})
	Debugf(format string, v ...interface{})
	Warnf(format string, v ...interface{})
	Errorf(format string, v ...interface{})
	Fatalf(format string, v ...interface{})
	Panicf(format string, v ...interface{})

	Print(v ...interface{})
	Printf(format string, v ...interface{})

	Close()
}

Logger is the interface for Logging in the Verto framework. A default implementation is provided along with a "nil" implementation.

type NilLogger

type NilLogger struct{}

NilLogger is a logger that implements the logging interface such that all its functions are no-ops

func (*NilLogger) Close

func (nl *NilLogger) Close() error

func (*NilLogger) Debug

func (nl *NilLogger) Debug(v ...interface{})

func (*NilLogger) Debugf

func (nl *NilLogger) Debugf(format string, v ...interface{})

func (*NilLogger) Error

func (nl *NilLogger) Error(v ...interface{})

func (*NilLogger) Errorf

func (nl *NilLogger) Errorf(format string, v ...interface{})

func (*NilLogger) Fatal

func (nl *NilLogger) Fatal(v ...interface{})

func (*NilLogger) Fatalf

func (nl *NilLogger) Fatalf(format string, v ...interface{})

func (*NilLogger) Info

func (nl *NilLogger) Info(v ...interface{})

func (*NilLogger) Infof

func (nl *NilLogger) Infof(format string, v ...interface{})

func (*NilLogger) Panic

func (nl *NilLogger) Panic(v ...interface{})

func (*NilLogger) Panicf

func (nl *NilLogger) Panicf(format string, v ...interface{})

func (*NilLogger) Print

func (nl *NilLogger) Print(v ...interface{})

func (*NilLogger) Printf

func (nl *NilLogger) Printf(format string, v ...interface{})

func (*NilLogger) Warn

func (nl *NilLogger) Warn(v ...interface{})

func (*NilLogger) Warnf

func (nl *NilLogger) Warnf(format string, v ...interface{})

type Plugin

type Plugin interface {
	Handle(c *Context, next http.HandlerFunc)
}

Plugin is a custom plugin definition for Verto that allows injections by context.

type PluginFunc

type PluginFunc func(c *Context, next http.HandlerFunc)

PluginFunc wraps functions as Verto Plugins

func (PluginFunc) Handle

func (pf PluginFunc) Handle(c *Context, next http.HandlerFunc)

Handle calls functions wrapped by VertoPluginFunc.

type ReadOnlyInjections

type ReadOnlyInjections interface {
	Get(key string) interface{}
	TryGet(key string) (interface{}, bool)
}

ReadOnlyInjections is provides a read-only interface for Injections. It is up to the implementor to ensure the implementation is read-only.

type ResourceFunc

type ResourceFunc func(c *Context) (interface{}, error)

ResourceFunc is the Verto-specific function for endpoint resource handling.

type ResponseFunc

type ResponseFunc func(response interface{}, c *Context)

ResponseFunc wraps functions so that they implement ResponseHandler

func (ResponseFunc) Handle

func (rf ResponseFunc) Handle(response interface{}, c *Context)

Handle calls the function wrapped by ResponseFunc.

type ResponseHandler

type ResponseHandler interface {

	// Handle handles the response. Context is guaranteed to be
	// populated if ResponseHandler is registered through Verto.
	Handle(response interface{}, c *Context)
}

ResponseHandler is the Verto-specific interface for response handlers. A default ResponseHandler is provided with Verto but it is recommended to bring your own ResponseHandler.

type StoppableListener

type StoppableListener struct {
	*net.TCPListener
	// contains filtered or unexported fields
}

StoppableListener is a TCPListener with the ability to do a clean stop.

func WrapListener

func WrapListener(listener net.Listener) (*StoppableListener, error)

WrapListener wraps an existing listener as a new StoppableListener. Currently only supports net.TCPListener pointers for wrapping.

func (*StoppableListener) Accept

func (sl *StoppableListener) Accept() (net.Conn, error)

Accept wraps the accept function and polls for a stop command every second.

func (*StoppableListener) Close

func (sl *StoppableListener) Close() error

Close sends a stop command to the listener.

type Verto

type Verto struct {
	Injections      *IContainer
	Logger          Logger
	ErrorHandler    ErrorHandler
	ResponseHandler ResponseHandler
	TLSConfig       *tls.Config
	// contains filtered or unexported fields
}

Verto is a simple and fast REST framework. It has a simple to use but powerful API that allows you to quickly create RESTful Go backends.

Example usage:

// Instantiates a new Verto instance and registers a hello world handler
// at GET /hello/world
v := verto.New()
v.Get("/hello/world", verto.ResourceFunc(func(c *verto.Context) {
	return "Hello, World!"
}))

Verto can be configured to use TLS by providing a *tls.Config. If a tls.Config is provided, Verto will automatically default to using TLS

Example:

v := verto.New()
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
  panic(err.Error())
}
v.TLSConfig = &tls.Config{
  Certificates: []tls.Certificate{cert}
}
v.Run()

func New

func New() *Verto

New returns a newly initialized Verto instance. The path /shutdown is automatically reserved as a way to cleanly shutdown the instance which is only available to calls from localhost.

func (*Verto) Add

func (v *Verto) Add(
	method, path string,
	rf ResourceFunc) *Endpoint

Add registers a specific method+path combination to a resource function and returns an Endpoint representing said resource

func (*Verto) AddHandler

func (v *Verto) AddHandler(
	method, path string,
	handler http.Handler) *Endpoint

AddHandler registers a specific method+path combination to an http.Handler and returns an Endpoint representing said resource

func (*Verto) Delete

func (v *Verto) Delete(path string, rf ResourceFunc) *Endpoint

Delete is a wrapper function around Add() that sets the method as DELETE

func (*Verto) DeleteHandler

func (v *Verto) DeleteHandler(path string, handler http.Handler) *Endpoint

DeleteHandler is a wrapper function around AddHandler() that sets the method as DELETE

func (*Verto) Get

func (v *Verto) Get(path string, rf ResourceFunc) *Endpoint

Get is a wrapper function around Add() that sets the method as GET

func (*Verto) GetHandler

func (v *Verto) GetHandler(path string, handler http.Handler) *Endpoint

GetHandler is a wrapper function around AddHandler() that sets the method as GET

func (*Verto) Group

func (v *Verto) Group(method, path string) *Group

func (*Verto) Post

func (v *Verto) Post(path string, rf ResourceFunc) *Endpoint

Post is a wrapper function around Add() that sets the method as POST

func (*Verto) PostHandler

func (v *Verto) PostHandler(path string, handler http.Handler) *Endpoint

PostHandler is a wrapper function around AddHandler() that sets the method as POST

func (*Verto) Put

func (v *Verto) Put(path string, rf ResourceFunc) *Endpoint

Put is a wrapper function around Add() that sets the method as PUT

func (*Verto) PutHandler

func (v *Verto) PutHandler(path string, handler http.Handler) *Endpoint

PutHandler is a wrapper function around AddHandler() that sets the method as PUT

func (*Verto) Run

func (v *Verto) Run()

Run runs Verto on address ":8080".

func (*Verto) RunOn

func (v *Verto) RunOn(addr string)

RunOn runs Verto on the specified address (e.g. ":8080"). RunOn by defaults adds a shutdown endpoint for Verto at /shutdown which can only be called locally.

func (*Verto) SetStrict

func (v *Verto) SetStrict(strict bool)

SetStrict sets whether to do strict path matching or not. If false, Verto will attempt to redirect trailing slashes to non-trailing slash paths if they exist and vice versa. The default is true which means Verto treats trailing slash as a different path than non-trailing slash

func (*Verto) SetVerbose

func (v *Verto) SetVerbose(verbose bool)

SetVerbose sets whether the Verto instance is verbose or not.

func (*Verto) Stop

func (v *Verto) Stop()

Stops the Verto instance

func (*Verto) Use

func (v *Verto) Use(plugin Plugin) *Verto

Use wraps a Plugin as a mux.PluginHandler and calls Verto.Use().

func (*Verto) UseHandler

func (v *Verto) UseHandler(handler http.Handler) *Verto

UseHandler wraps an http.Handler as a mux.PluginHandler and calls Verto.Use().

func (*Verto) UsePluginHandler

func (v *Verto) UsePluginHandler(handler mux.PluginHandler) *Verto

UsePluginHandler registers a mux.PluginHandler as a global plugin. to run for all groups and paths registered to the Verto instance. Plugins are called in order of definition.

Directories

Path Synopsis
Package mux provides a path multiplexer and interfaces for plugin handling and custom path matching.
Package mux provides a path multiplexer and interfaces for plugin handling and custom path matching.
plugins is package providing a number of common middleware plugins for the Verto framework.
plugins is package providing a number of common middleware plugins for the Verto framework.

Jump to

Keyboard shortcuts

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