navaros

package module
v1.0.0-beta-9 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2024 License: MIT Imports: 14 Imported by: 1

README

Please note that Navaros is still in early development. Any and all feedback and testing is greatly appreciated.

If you encounter a bug please report it.

Navaros is a simple and fast HTTP router for Go. It's designed to be simple to use and get out of your way so you can focus on building awesome things.

import (
  "net/http"
  "github.com/RobertWHurst/navaros"
  "github.com/RobertWHurst/navaros/middleware/json"
)

func main() {
  router := navaros.New()

  widgets := []*Widget{}

  router.Use(json.Middleware(nil))

  router.Post("/widget", func (ctx *navaros.Context) {
    widget := &Widget{}
    if ctx.UnmarshalRequestBody(widget); err != nil {
      ctx.Status = 404
      ctx.Body = map[string]string{"error": "invalid request body"}
      return
    }
    
    widget.ID = GenId()
    widgets = append(widgets, widget)

    ctx.Status = 201
  })

  router.Get("/widget", func (ctx *navaros.Context) {
    ctx.Status = 200
    ctx.Body = widgets
  })

  router.Get("/widget/:id", func (ctx *navaros.Context) {
    id := ctx.Params().Get("id")

    for _, widget := range widgets {
      if widget.ID == id {
        ctx.Status = 200
        ctx.Body = widget
        return
      }
    }

    ctx.Status = 404
  })

  server := http.Server{
    Addr: ":8080",
    Handler: router
  }

  server.ListenAndServe()
}

Features

  • Simple and fast
  • Middleware support
  • Parameterized routes
  • Streaming request and response bodies
  • Marshal and unmarshal API for body related middleware
  • Unmarshal request bodies into structs
  • handler panic recovery
  • Request and response data organized into a single context object
  • context support for ending handler logic after cancelled requests
  • No dependencies other than the standard library
  • Powerful route pattern matching
  • Nestable routers

Installation

go get github.com/RobertWHurst/navaros

Usage

Navaros is designed to be simple to use and get out of your way so you can focus on building awesome things. It's API is designed to be simple and intuitive.

Creating a router

In order to get started you need to create a router. A router is an http.Handler so to use it you just need to assign it as http server's handler.

router := navaros.New()

server := http.Server{
  Addr: ":8080",
  Handler: router
}

server.ListenAndServe()

Adding middleware

Let's say your going to be building an API and you want to use JSON as your request and response body format. Navaros comes with JSON middleware for this purpose. Now the request body will be buffered, and you will be able to unmarshal it into a struct within you handlers.

router.Use(json.Middleware(nil))

Adding a route and unmarshaling a request body

Now let's add a handler to create a widget. We'll use the Post method to register a handler for the POST method on the /widget path.

type Widget struct {
  Name string `json:"name"`
  ...
}

router.Post("/widget", func (ctx *navaros.Context) {
  widget := &Widget{}
  if ctx.UnmarshalRequestBody(widget); err != nil {
    ctx.Status = 400
    ctx.Body = map[string]string{"error": "invalid request body"}
    return
  }
  
  ...

  ctx.Status = 201
})

Adding a parameterized route

Now let's add a handler to get a widget by it's id. We'll use the Get method to register a handler for the GET method on the /widget/:id path. The :id portion of the path is a parameter. Parameters are accessible via the Params method on the context.

router.Get("/widget/:id", func (ctx *navaros.Context) {
  id := ctx.Params().Get("id")

  ...
})

Note that you can do much more with route patterns. We'll cover that later in the readme.

Context cancellation

Now let's say we have a handler that might be doing some expensive work. We don't want to waste resources on requests that have been cancelled. For any logic in your handler that supports go's context API you can actually pass the handler context to it as ctx implements the context interface.

router.Post("/report", func (ctx *navaros.Context) {
  reportCfg := &ReportConfiguration{}
  if err := ctx.UnmarshalRequestBody(reportCfg); err != nil {
    ctx.Status = 400
    ctx.Body = map[string]string{"error": "invalid request body"}
    return
  }
  
  report, err := reportGenerator.GenerateReport(ctx, reportCfg)

  ctx.Status = 200
  ctx.Body = report
})

If the request is cancelled the GenerateReport function can check the context for cancellation and return early.

Streaming request and response bodies

Navaros supports streaming request and response bodies. This is useful for handling large files or streaming data. Provided you are not using Middleware that buffers the request body you can read the bytes as they come in.

router.Post("/upload", func (ctx *navaros.Context) {
  ctx.MaxRequestBodySize = 1024 * 1024 * 100 // 100MB

  reader := ctx.RequestBodyReader()

  ...
})

You can also stream the response body.

router.Get("/download/:id", func (ctx *navaros.Context) {
  id := ctx.Params().Get("id")
  fileReader, err := fileManager.GetFileReader(id)
  if err != nil {
    if err == fileManager.ErrFileNotFound {
      ctx.Status = 404
      return
    }
    panic(err)
  }

  ctx.Status = 200
  ctx.Body = fileReader
})

Nesting routers

Navaros supports nesting routers. This is useful for breaking up your routes into logical groups. For example you might break your resources into packages - each package having it's own router.

Your root router might look something like this.

router := navaros.New()

router.Use(json.Middleware(nil))

router.Use(widgets.Router)
router.Use(gadgets.Router)
router.Use(gizmos.Router)

And each of your resource routers might look something like this.

package widgets

import (
  "github.com/RobertWHurst/navaros"
)

var Router = navaros.New()

func init() {
  Router.Post("/widget", CreateWidget)
  Router.Get("/widget", GetWidgets)
  Router.Get("/widget/:id", GetWidgetByID)
}

func CreateWidget(ctx *navaros.Context) {
  ...
}

func GetWidgets(ctx *navaros.Context) {
  ...
}

func GetWidgetByID(ctx *navaros.Context) {
  ...
}

Route patterns

Navaros supports fairly powerful route patterns. The following is a list of supported pattern chunk types.

  • Static - /a/b/c - Matches the exact path
  • Wildcard - /a/*/c - Pattern segments with a single * match any path segment
  • Dynamic - /a/:b/c - Pattern segments prefixed with : match any path segment and the value of this segment from the matched path is available via the Params method, and will be filled under a key matching the name of the pattern segment, ie: pattern of /a/:b/c will match /a/1/c and the value of b in the params will be 1

Pattern chunks can also be suffixed with additional modifiers.

  • ? - Optional - /a/:b?/c - Matches /a/c and /a/1/c
  • * - Greedy - /a/:b*/c - Matches /a/c and /a/1/2/3/c
  • + - One or more - /a/:b+/c - Matches /a/1/c and /a/1/2/3/c but not /a/c

You can also provide a regular expression to restrict matches for a pattern chunk.

  • /a/:b(\d+)/c - Matches /a/1/c and /a/2/c but not /a/b/c

You can escape any of the special characters used by these operators by prefixing them with a \.

  • /a/\:b/c - Matches /a/:b/c

And all of these can be combined.

  • /a/:b(\d+)/*?/(d|e)+ - Matches /a/1/d, /a/1/e, /a/2/c/d/e/f/g, and /a/3/1/d but not /a/b/c, /a/1, or /a/1/c/f

This is all most likely overkill, but if you ever need it, it's here.

Handler and Middleware ordering

Handlers and middleware are executed in the order they are added to the router. This means that a handler added before another will always be checked for a match against the incoming request first regardless of the path pattern. This means you can easily predict how your handlers will be executed.

It also means that your handlers with more specific patterns should be added before any others that may share a common match.

router.Get("/album/:id(\d{24})", GetWidgetByID)
router.Get("/album/:name", GetWidgetsByName)

Binding different HTTP methods

The router has a method for the following HTTP methods.

  • Get - Handles GET requests - Should be used for reading
  • Post - Handles POST requests - Should be used for creating
  • Put - Handles PUT requests - Should be used for updating
  • Patch - Handles PATCH requests - Should be used for updating
  • Delete - Handles DELETE requests - Should be used for deleting
  • Head - Handles HEAD requests - Should be used checking for existence
  • Options - Handles OPTIONS requests - Used for CORS

There is also a few non HTTP method methods.

  • All - Handles all requests matching the pattern regardless of method
  • Use - Handles all requests like all, but a pattern can be omitted

Passing a request on to the next handler - middleware

If you want to pass a request on to the next handler you can call the Next method on the context. This will execute the next handler in the chain.

router.All("/admin/**", func (ctx *navaros.Context) {
  if !IsAuthenticated(ctx) {
    ctx.Status = 401
    return
  }
  ctx.Next()
})

This is what makes a handler into middleware.

Interestingly you can also add logic after the Next call. This is useful for doing things with the response after a handler executed during the Next call has a written it.

router.Use(func (ctx *navaros.Context) {
  ctx.Next()
  if ctx.Status == 404 && ctx.Body == nil {
    ctx.Status = 404
    ctx.Body = map[string]string{"error": "not found"}
  }
})

Roadmap

Now that the core of Navaros is complete I'm going to be focusing on adding more middleware and adding websocket support.

Websockets are going to be an important part of this project as I want to support building realtime applications with Navaros.

Help Welcome

If you want to support this project by throwing be some coffee money It's greatly appreciated.

sponsor

If your interested in providing feedback or would like to contribute please feel free to do so. I recommend first opening an issue expressing your feedback or intent to contribute a change, from there we can consider your feedback or guide your contribution efforts. Any and all help is greatly appreciated since this is an open source effort after all.

Thank you!

Documentation

Index

Constants

This section is empty.

Variables

View Source
var MaxRequestBodySize int64 = 1024 * 1024 * 10 // 10MB

MaxRequestBodySize is the maximum size of a request body. Changing this value will affect all requests. Set to -1 to disable the limit. If MaxRequestBodySize is set on the context it will override this value. This setting is useful for preventing denial of service attacks. It is not recommended to set this value to -1 unless you know what you are doing!!!

View Source
var PrintHandlerErrors = false

Functions

func CtxFinalize

func CtxFinalize(ctx *Context)

CtxFinalize allows libraries to call the finalize method on a context. finalize figures out the final status code, headers, and body for the response. This is nomally called by the router, but can be called by libraries which wish to extend or encapsulate the functionality of Navaros.

func CtxSetDeadline

func CtxSetDeadline(ctx *Context, deadline time.Time)

CtxSetDeadline sets a deadline for the context. This allows libraries to limit the amount of time a handler can take to process a request.

Types

type Context

type Context struct {
	Status  int
	Headers http.Header
	Cookies []*http.Cookie
	Body    any

	MaxRequestBodySize int64

	Error           error
	ErrorStack      string
	FinalError      error
	FinalErrorStack string
	// contains filtered or unexported fields
}

Context represents a request and response. Navaros handlers access the request and build the response through the context.

func NewContext

func NewContext(res http.ResponseWriter, req *http.Request, handlers ...any) *Context

NewContext creates a new Context from go's http.ResponseWriter and http.Request. It also takes a variadic list of handlers. This is useful for creating a new Context outside of a router, and can be used by libraries which wish to extend or encapsulate the functionality of Navaros.

func NewContextWithNode

func NewContextWithNode(res http.ResponseWriter, req *http.Request, firstHandlerNode *HandlerNode) *Context

NewContextWithNode creates a new Context from go's http.ResponseWriter and http.Request. It also takes a HandlerNode - a link in a chain of handlers. This is useful for creating a new Context outside of a router, and can be used by libraries which wish to extend or encapsulate the functionality of Navaros. For example, implementing a custom router.

func NewSubContextWithNode

func NewSubContextWithNode(ctx *Context, firstHandlerNode *HandlerNode) *Context

NewSubContextWithNode creates a new Context from an existing Context. This is useful when you want to create a new Context from an existing one, but with a different handler chain. Note that when the end of the sub context's handler chain is reached, the parent context's handler chain will continue.

func (*Context) Deadline

func (c *Context) Deadline() (time.Time, bool)

Deadline returns the deadline of the request. Deadline is part of the go context.Context interface.

func (*Context) Done

func (c *Context) Done() <-chan struct{}

Done added for compatibility with go's context.Context. Alias for UntilFinish(). Done is part of the go context.Context interface.

func (*Context) Err

func (c *Context) Err() error

Err returns the final error of the request. Will be nil if the request is still being served even if an error has occurred. Populated once the request is done. Err is part of the go context.Context interface.

func (*Context) Flush

func (c *Context) Flush()

Flush sends any bytes buffered in the response body to the client. Buffering is controlled by go's http.ResponseWriter.

func (Context) Get

func (s Context) Get(key string) any

func (*Context) Method

func (c *Context) Method() HTTPMethod

Method returns the HTTP method of the request.

func (*Context) Next

func (c *Context) Next()

Next calls the next handler in the chain. This is useful for creating middleware style handlers that work on the context before and/or after the responding handler.

func (*Context) Params

func (c *Context) Params() RequestParams

Params returns the parameters of the request. These are defined by the route pattern used to bind each handler, and may be different for each time next is called.

func (*Context) Path

func (c *Context) Path() string

Path returns the path of the request.

func (*Context) Protocol

func (c *Context) Protocol() string

Protocol returns the http protocol version of the request.

func (*Context) ProtocolMajor

func (c *Context) ProtocolMajor() int

ProtocolMajor returns the major number in http protocol version.

func (*Context) ProtocolMinor

func (c *Context) ProtocolMinor() int

ProtocolMinor returns the minor number in http protocol version.

func (*Context) Query

func (c *Context) Query() url.Values

Query returns the query parameters of the request.

func (*Context) Request

func (c *Context) Request() *http.Request

Request returns the underlying http.Request object.

func (*Context) RequestBodyReader

func (c *Context) RequestBodyReader() io.ReadCloser

RequestBodyReader returns a reader setup to read in the request body. This is useful for streaming the request body, or for middleware which decodes the request body. Without body handling middleware, the request body reader is the only way to access request body data.

func (*Context) RequestContentLength

func (c *Context) RequestContentLength() int64

RequestContentLength returns the length of the request body if provided by the client.

func (*Context) RequestCookie

func (c *Context) RequestCookie(name string) (*http.Cookie, error)

RequestCookies returns the value of a request cookie by name. Returns nil if the cookie does not exist.

func (*Context) RequestHeaders

func (c *Context) RequestHeaders() http.Header

RequestHeaders returns the request headers.

func (*Context) RequestHost

func (c *Context) RequestHost() string

RequestHost returns the host of the request. Useful for determining the source of the request.

func (*Context) RequestRawURI

func (c *Context) RequestRawURI() string

RequestRawURI returns the raw URI of the request. This will be the original value from the request headers.

func (*Context) RequestRemoteAddress

func (c *Context) RequestRemoteAddress() string

RequestRemoteAddress returns the remote address of the request. Useful for determining the source of the request.

func (*Context) RequestTLS

func (c *Context) RequestTLS() *tls.ConnectionState

RequestTLS returns the TLS connection state of the request if the request is using TLS.

func (*Context) RequestTrailers

func (c *Context) RequestTrailers() http.Header

RequestTrailers returns the trailing headers of the request if set.

func (*Context) RequestTransferEncoding

func (c *Context) RequestTransferEncoding() []string

RequestTransferEncoding returns the transfer encoding of the request

func (*Context) ResponseWriter

func (c *Context) ResponseWriter() http.ResponseWriter

ResponseWriter returns the underlying http.ResponseWriter object.

func (Context) Set

func (s Context) Set(key string, value any)

func (*Context) SetRequestBodyReader

func (c *Context) SetRequestBodyReader(reader io.Reader)

Allows middleware to intercept the request body reader and replace it with their own. This is useful transformers that re-write the request body in a streaming fashion. It's also useful for transformers that re-encode the request body.

func (*Context) SetRequestBodyUnmarshaller

func (c *Context) SetRequestBodyUnmarshaller(unmarshaller func(into any) error)

SetRequestBodyUnmarshaller sets the request body unmarshaller. Middleware that parses request bodies should call this method to set the unmarshaller.

func (*Context) SetResponseBodyMarshaller

func (c *Context) SetResponseBodyMarshaller(marshaller func(from any) (io.Reader, error))

SetResponseBodyMarshaller sets the response body marshaller. Middleware that encodes response bodies should call this method to set the marshaller.

func (*Context) URL

func (c *Context) URL() *url.URL

URL returns the URL of the request.

func (*Context) UnmarshalRequestBody

func (c *Context) UnmarshalRequestBody(into any) error

UnmarshalRequestBody unmarshals the request body into a given value. Note that is method requires SetRequestBodyUnmarshaller to be called first. This likely is done by middleware for parsing request bodies.

func (*Context) Value

func (c *Context) Value(key any) any

Value is a noop for compatibility with go's context.Context.

func (*Context) Write

func (c *Context) Write(bytes []byte) (int, error)

Write writes bytes to the response body. This is useful for streaming the response body, or for middleware which encodes the response body.

type HTTPMethod

type HTTPMethod string

HTTPMethod represents an HTTP method.

const (
	// All represents all HTTP methods.
	All HTTPMethod = "ALL"
	// Post represents the HTTP POST method.
	Post HTTPMethod = "POST"
	// Get represents the HTTP GET method.
	Get HTTPMethod = "GET"
	// Put represents the HTTP PUT method.
	Put HTTPMethod = "PUT"
	// Patch represents the HTTP PATCH method.
	Patch HTTPMethod = "PATCH"
	// Delete represents the HTTP DELETE method.
	Delete HTTPMethod = "DELETE"
	// Options represents the HTTP OPTIONS method.
	Options HTTPMethod = "OPTIONS"
	// Head represents the HTTP HEAD method.
	Head HTTPMethod = "HEAD"
)

func HTTPMethodFromString

func HTTPMethodFromString(method string) HTTPMethod

HTTPMethodFromString converts a string to an HTTPMethod. If the string is not a valid HTTP method, an error is returned.

type Handler

type Handler interface {
	Handle(ctx *Context)
}

Handler is a handler object interface. Any object that implements this interface can be used as a handler in a handler chain.

type HandlerNode

type HandlerNode struct {
	Method                  HTTPMethod
	Pattern                 *Pattern
	HandlersAndTransformers []any
	Next                    *HandlerNode
}

HandlerNode is used to build the handler chains used by the context. The router builds a chain from these objects then attaches them to the context. It then calls Next on the context to execute the chain.

type Pattern

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

Pattern is used to compare and match request paths to route patterns. Patterns are used by the router to determine which handlers to execute for a given request.

func NewPattern

func NewPattern(patternStr string) (*Pattern, error)

NewPattern creates a new pattern from a string. The string should be a valid route pattern. If the string is not a valid route pattern, an error is returned.

func (*Pattern) Match

func (p *Pattern) Match(path string) (RequestParams, bool)

Match compares a path to the pattern and returns a map of named parameters extracted from the path as per the pattern. If the path matches the pattern, the second return value will be true. If the path does not match the pattern, the second return value will be false.

func (*Pattern) MatchInto

func (p *Pattern) MatchInto(path string, params *RequestParams) bool

func (*Pattern) String

func (p *Pattern) String() string

String returns the string representation of the pattern.

type Redirect

type Redirect struct {
	To string
}

Redirect represents an HTTP redirect. If you want to redirect a request in a handler, you can initialize a Redirect with a target relative path or absolute URL, and set it as the body of the context. This will cause Navaros to send the client a Location header with the redirect url, and a 302 status code. The status code can be changed by setting the Status field of the context.

type RequestParams

type RequestParams map[string]string

RequestParams represents the parameters extracted from the request path. Parameters are extracted from the path by matching the request path to the route pattern for the handler node. These may change each time Next is called on the context.

func (RequestParams) Get

func (p RequestParams) Get(key string) string

Get returns the value of a given parameter key. If the key does not exist, an empty string is returned.

type RouteDescriptor

type RouteDescriptor struct {
	Method  HTTPMethod
	Pattern *Pattern
}

RouteDescriptor is a struct that is generated by the router when the public variants of the handler binding methods (named after their respective http method) are called. The router has a RouteDescriptors method which returns these objects, and can be used to build a api map, or pre-filter requests before they are passed to the router. This is most useful for libraries that wish to extend the functionality of Navaros.

func (*RouteDescriptor) MarshalJSON

func (r *RouteDescriptor) MarshalJSON() ([]byte, error)

MarshalJSON returns the JSON representation of the route descriptor.

func (*RouteDescriptor) UnmarshalJSON

func (r *RouteDescriptor) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the JSON representation of the route descriptor.

type Router

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

Router is the main component of Navaros. It is an HTTP handler that can be used to handle requests, and route them to the appropriate handlers. It implements the http.Handler interface, and can be used as a handler in standard http servers. It also implements Navaros' own Handler interface, which allows nesting routers for better code organization.

func NewRouter

func NewRouter() *Router

NewRouter creates a new router.

func (*Router) All

func (r *Router) All(path string, handlersAndTransformers ...any)

All allows binding handlers to all HTTP methods at a given route path pattern.

func (*Router) Delete

func (r *Router) Delete(path string, handlersAndTransformers ...any)

Delete allows binding handlers to the DELETE HTTP method at a given route path pattern.

func (*Router) Get

func (r *Router) Get(path string, handlersAndTransformers ...any)

Get allows binding handlers to the GET HTTP method at a given route path pattern.

func (*Router) Handle

func (r *Router) Handle(ctx *Context)

Handle is for the purpose of taking an existing context, and running it through the mux's handler chain. If the last handler calls next, it will call next on the original context.

func (*Router) Head

func (r *Router) Head(path string, handlersAndTransformers ...any)

Head allows binding handlers to the HEAD HTTP method at a given route path pattern.

func (*Router) Options

func (r *Router) Options(path string, handlersAndTransformers ...any)

Options allows binding handlers to the OPTIONS HTTP method at a given route path pattern.

func (*Router) Patch

func (r *Router) Patch(path string, handlersAndTransformers ...any)

Patch allows binding handlers to the PATCH HTTP method at a given route path pattern.

func (*Router) Post

func (r *Router) Post(path string, handlersAndTransformers ...any)

Post allows binding handlers to the POST HTTP method at a given route path pattern.

func (*Router) PublicAll

func (r *Router) PublicAll(path string, handlersAndTransformers ...any)

PublicAll is the same as All, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicDelete

func (r *Router) PublicDelete(path string, handlersAndTransformers ...any)

PublicDelete is the same as Delete, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicGet

func (r *Router) PublicGet(path string, handlersAndTransformers ...any)

PublicGet is the same as Get, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicHead

func (r *Router) PublicHead(path string, handlersAndTransformers ...any)

PublicHead is the same as Head, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicOptions

func (r *Router) PublicOptions(path string, handlersAndTransformers ...any)

PublicOptions is the same as Options, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicPatch

func (r *Router) PublicPatch(path string, handlersAndTransformers ...any)

PublicPatch is the same as Patch, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicPost

func (r *Router) PublicPost(path string, handlersAndTransformers ...any)

PublicPost is the same as Post, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) PublicPut

func (r *Router) PublicPut(path string, handlersAndTransformers ...any)

PublicPut is the same as Put, but it also adds the route descriptor to the router's list of public route descriptors.

func (*Router) Put

func (r *Router) Put(path string, handlersAndTransformers ...any)

Put allows binding handlers to the PUT HTTP method at a given route path pattern.

func (*Router) RouteDescriptors

func (r *Router) RouteDescriptors() []*RouteDescriptor

RouteDescriptors returns a list of all the route descriptors that this router is responsible for. Useful for gateway configuration.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(res http.ResponseWriter, req *http.Request)

ServeHTTP allows the router to be used as a handler in standard go http servers. It handles the incoming request - creating a context and running the handler chain over it, then finalizing the response.

func (*Router) Use

func (r *Router) Use(handlersAndTransformers ...any)

Use is for middleware handlers. It allows the handlers to be executed on every request. If a path is provided, the middleware will only be executed on requests that match the path.

Note that routers are middleware handlers, and so can be passed to Use to attach them as sub-routers. It's also important to know that if you provide a path with a router, the router will set the mount path as the base path for all of it's handlers. This means that if you have a router with a path of "/foo", and you bind a handler with a path of "/bar", the handler will only be executed on requests with a path of "/foo/bar".

type RouterHandler

type RouterHandler interface {
	RouteDescriptors() []*RouteDescriptor
	Handle(ctx *Context)
}

RouterHandler is handled nearly identically to a Handler, but it also provides a list of route descriptors which are collected by the router. These will be merged with the other route descriptors already collected. This use for situation where a handler may do more sub-routing, and the allows the handler to report the sub-routes to the router, rather than it's base path.

type Transformer

type Transformer interface {
	TransformRequest(ctx *Context)
	TransformResponse(ctx *Context)
}

Transformer is a special type of handler object that can be used to transform the context before and after handlers have processed the request. This is most useful for modifying or re-encoding the request and response bodies.

Directories

Path Synopsis
middleware

Jump to

Keyboard shortcuts

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