web

package
v0.0.0-...-519d24f Latest Latest
Warning

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

Go to latest
Published: May 5, 2020 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Overview

Package web provides simple web application framework for golang

Index

Examples

Constants

View Source
const (
	RouterLoggerKey = "web.router"
)

LoggerKeys

Variables

View Source
var DefaultOption = &Option{
	HMACKey: xhmac.NewBase64([]byte("github.com/yssk22"), sha256.New),
}

DefaultOption is an *Option object for defaults and can be updated by applications

Functions

This section is empty.

Types

type Handler

type Handler interface {
	// Process serve http request and return the new http request and/or *response.Response value,
	Process(*Request, NextHandler) *response.Response
}

Handler is an interface to process the request and make a *response.Response

type HandlerFunc

type HandlerFunc func(*Request, NextHandler) *response.Response

HandlerFunc is a func to implement Handler interface.

func (HandlerFunc) Process

func (h HandlerFunc) Process(r *Request, next NextHandler) *response.Response

Process implements Handler.Process

type NextHandler

type NextHandler func(*Request) *response.Response

NextHandler is an alias to call the next handler in pipeline

type Option

type Option struct {
	// Option for hmac signature key, must not be nil. The default key is "github.com/yssk22"
	HMACKey *xhmac.Base64
	// Option to initialize the request context. The default is nil.
	InitContext func(r *http.Request) context.Context

	// Optioin to accept or reject the requests to router debugger endpoints
	//   - if this field is nil, always reject.
	//   - if this field set a func and returns an error, the request is rejected.
	//   - if this field set a func and returns nil, the request is processed.
	OnDebugRequest func(r *Request) error
}

Option provies the option fields for web package.

type PathPattern

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

PathPattern is a struct to support path parameters and matches incoming request paths.

func CompilePathPattern

func CompilePathPattern(pattern string) (*PathPattern, error)

CompilePathPattern compiles the path pattern string to *PathPattern A path parameter name must be [a-zA-Z0-9_]+ with : and * prefix to define the matching storategy.

  • /:something/ is a pattern to match something (except '/') on the path and capture the parameter value as 'something'.
  • /*anything/ is a pattern to match anything (including '/') on the path and capture the parameter value as 'anything'
  • /*/ is a pattern to match anything and no parameter capturing.

func MustCompilePathPattern

func MustCompilePathPattern(pattern string) *PathPattern

MustCompilePathPattern is like CompilePathPattern but panics if an error occurrs.

func (*PathPattern) GetParamNames

func (pattern *PathPattern) GetParamNames() []string

GetParamNames returns a list of parameter names

func (*PathPattern) Match

func (pattern *PathPattern) Match(path string) (*keyvalue.GetProxy, bool)

Match execute the matching with the given path and return the parameter values or nil

Example (WithAnything)
p := MustCompilePathPattern(
	"/path/to/*anything",
)
if param, ok := p.Match("/path/to/a.html"); ok {
	fmt.Printf(":anything => %q\n", param.GetStringOr("anything", ""))
}
if param, ok := p.Match("/path/to/"); ok {
	fmt.Printf(":anything => %q\n", param.GetStringOr("anything", ""))
}
Output:

:anything => "a.html"
:anything => ""
Example (WithSomething)
p := MustCompilePathPattern(
	"/path/to/:something.html",
)
if param, ok := p.Match("/path/to/a.html"); ok {
	fmt.Printf(":something => %q", param.GetStringOr("something", ""))
}
Output:

:something => "a"
Example (WithURLEncoded)
p := MustCompilePathPattern(
	"/path/to/:something.html",
)
if _, ok := p.Match("/path/to/foo/bar.html"); !ok {
	fmt.Println("Not matched")
}
if param, ok := p.Match("/path/to/foo%2Fbar.html"); ok {
	fmt.Printf(":something => %q\n", param.GetStringOr("something", ""))
}
if param, ok := p.Match("/path/to/foo%252Fbar.html"); ok {
	fmt.Printf(":something => %q\n", param.GetStringOr("something", ""))
}
Output:

Not matched
:something => "foo/bar"
:something => "foo/bar"

type Request

type Request struct {
	*http.Request

	// common request scoped values
	ID      uuid.UUID
	Params  *keyvalue.GetProxy
	Query   *keyvalue.GetProxy
	Form    *keyvalue.GetProxy
	Cookies *keyvalue.GetProxy

	Option *Option
}

Request is a wrapper for net/http.Request The original `*net/http.Request` functions and fields are embedded in struct and provides some utility functions (especially to support context.Context)

func FromContext

func FromContext(ctx context.Context) *Request

FromContext returns a *Request associated with the context.

func NewRequest

func NewRequest(r *http.Request, option *Option) *Request

NewRequest returns a new *Request

func (*Request) Get

func (r *Request) Get(key interface{}) (interface{}, error)

Get implements keyvalue.Getter to enable keyvalue.GetProxy for context values.

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

WithContext returns a shallow copy of r with its context changed to ctx. The provided ctx must be non-nil.

func (*Request) WithValue

func (r *Request) WithValue(key interface{}, value interface{}) *Request

WithValue sets the request-scoped value with the in-flight http request and return a shallow copied request. This is shorthand for `req.WithContext(context.WithValue(req.Context(), key, value))`

type Router

type Router interface {
	Use(...Handler)
	All(string, ...Handler)
	Get(string, ...Handler)
	Post(string, ...Handler)
	Put(string, ...Handler)
	Delete(string, ...Handler)
	ServeHTTP(http.ResponseWriter, *http.Request)
}

Router is an interface to set up http router

Example
router := NewRouter(nil)
router.Get("/path/to/:page.html",
	HandlerFunc(func(req *Request, _ NextHandler) *response.Response {
		return response.NewText(req.Context(), req.Params.GetStringOr("page", ""))
	}),
)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/path/to/bar.html", nil)
router.ServeHTTP(w, req)
fmt.Printf("*response.Response: %q", w.Body)
Output:

*response.Response: "bar"
Example (MultipleHandlerPipeline)
router := NewRouter(nil)
router.Get("/path/to/:page.html",
	HandlerFunc(func(req *Request, next NextHandler) *response.Response {
		if req.Params.GetStringOr("page", "") == "first" {
			return response.NewText(req.Context(), "First Handler")
		}
		return next(req)
	}),
	HandlerFunc(func(req *Request, next NextHandler) *response.Response {
		// This handler is reached only when the first handler returns nil
		if req.Params.GetStringOr("page", "") == "second" {
			return response.NewText(req.Context(), "Second Handler")
		}
		return nil
	}),
)
for _, s := range []string{"first", "second"} {
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", fmt.Sprintf("/path/to/%s.html", s), nil)
	router.ServeHTTP(w, req)
	fmt.Printf("*response.Response: %q\n", w.Body)
}
Output:

*response.Response: "First Handler"
*response.Response: "Second Handler"
Example (MultipleRoute)
router := NewRouter(nil)
router.Get("/:key.html", HandlerFunc(func(req *Request, next NextHandler) *response.Response {
	return next(req.WithValue(
		"my-middleware-key",
		req.Params.GetStringOr("key", "default"),
	))
}))
router.Get("/a.html",
	HandlerFunc(func(req *Request, next NextHandler) *response.Response {
		v, _ := req.Get("my-middleware-key")
		return response.NewText(req.Context(), fmt.Sprintf("a-%s", v))
	}),
)
router.Get("/b.html",
	HandlerFunc(func(req *Request, next NextHandler) *response.Response {
		v, _ := req.Get("my-middleware-key")
		return response.NewText(req.Context(), fmt.Sprintf("b-%s", v))
	}),
)

w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/a.html", nil)
router.ServeHTTP(w, req)
fmt.Printf("*response.Response: %q\n", w.Body)

w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/b.html", nil)
router.ServeHTTP(w, req)
fmt.Printf("*response.Response: %q\n", w.Body)

// not found route even /:key.html handles some
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/c.html", nil)
router.ServeHTTP(w, req)
fmt.Printf("*response.Response: %q\n", w.Body)
Output:

*response.Response: "a-a"
*response.Response: "b-b"
*response.Response: "not found"

func NewRouter

func NewRouter(option *Option) Router

NewRouter returns a new *Router

Directories

Path Synopsis
api
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
generator/example
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
generator/example/types
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
Code generated by github.com/yssk22/go/generator DO NOT EDIT.
middleware
oauth2
Package oauth2 provides oauth2 middleware
Package oauth2 provides oauth2 middleware
session/sessiontest
Package sessiontest provides session test helper
Package sessiontest provides session test helper
Package value provides lazy.Value for web context.
Package value provides lazy.Value for web context.

Jump to

Keyboard shortcuts

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