htadaptor

package module
v0.0.9 Latest Latest
Warning

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

Go to latest
Published: Nov 27, 2023 License: MIT Imports: 11 Imported by: 0

README

Hyper Text Adaptors

Package htadaptor provides convenient generic domain logic adaptors for HTTP handlers. It eliminates boiler plate code, increases security by enforcing read limits and struct validation, and reduces bugs by providing a more intuitive request data parsing API than the standard library.

Why do you need this package? An HTTP request contains at least five various sources of input that your HTTP handlers may consider: URL path, URL query, headers, cookies, and the request body. Much of the code that you have to write manually is wrestling those inputs into a struct. htadaptor can do all of it for you:

// lets make a slightly ridiculous example [http.Handler]:
myHandler := htadaptor.Must(htadaptor.NewUnaryFuncAdaptor(
  // your domain function call
  func(ctx context.Context, myInputStruct) (myOutputStruct, error) {
    // ... myInputStruct is passed in already validated
    // ... the fields of myInputStruct will be filled in
    //     with values from sources specified below
  },
  htadaptor.WithPathValues("slug"),           // (1) URL routing path
  htadaptor.WithQueryValues("search"),        // (2) URL query
  htadaptor.WithHeaderValues("accessToken"),  // (3) header
  htadaptor.WithCookieValues("sessionID"),    // (4) cookie
  // (5) JSON, URL-encoded or MIME-encoded body is always parsed last
))

Adaptors address all common function signatures of domain logic calls for both structs and single strings:

Struct Adaptor Parameter Values Return Values
UnaryFunc context, inputStruct any, error
NullaryFunc context any, error
VoidFunc context, inputStruct error

Each inputStruct must implement htadaptor.Validatable for safety. String adaptors are best when only one request value is needed:

String Adaptor Parameter Values Return Values
UnaryStringFunc context, string any, error
VoidStringFunc context, string error

Installation

go get github.com/dkotik/htadaptor@latest

Basic Usage

mux := http.NewServeMux()
mux.Handle("/api/v1/order", htadaptor.Must(
  htadaptor.NewUnaryFuncAdaptor(myService.Order),
))

See examples folder for most common project uses.

Adaptor Options

Extractors

Credits

Package includes reflection schema decoder from Gorilla toolkit.

Documentation

Overview

Package htadaptor provides generic domain logic adaptors for HTTP handlers. Adaptors come in three flavors:

1. UnaryFunc: func(context, inputStruct) (outputStruct, error) 2. NullaryFunc: func(context) (outputStruct, error) 3. VoidFunc: func(context, inputStruct) error

Each input requires implementation of Validatable for safety. Validation errors are decorated with the correct http.StatusUnprocessableEntity status code.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoStringValue = errors.New("empty value")

Functions

func Must

func Must(h http.Handler, err error) http.Handler

Types

type CookieValueExtractor added in v0.0.6

type CookieValueExtractor string

func NewCookieValueExtractor added in v0.0.6

func NewCookieValueExtractor(name string) CookieValueExtractor

func (CookieValueExtractor) ExtractStringValue added in v0.0.6

func (e CookieValueExtractor) ExtractStringValue(r *http.Request) (string, error)

type Decoder

type Decoder interface {
	Decode(any, *http.Request) error
}

type Encoder

type Encoder interface {
	Encode(http.ResponseWriter, any) error
}

type EncoderFunc

type EncoderFunc func(http.ResponseWriter, any) error

func (EncoderFunc) Encode

func (f EncoderFunc) Encode(w http.ResponseWriter, v any) error

type Error

type Error interface {
	error
	HyperTextStatusCode() int
}

type FuncType

type FuncType uint8
const (
	FuncTypeUnary FuncType = iota + 1
	FuncTypeNullary
	FuncTypeVoid
)

func Detect

func Detect(f any) (FuncType, error)

type HeaderValueExtractor added in v0.0.4

type HeaderValueExtractor string

func NewHeaderValueExtractor added in v0.0.4

func NewHeaderValueExtractor(name string) HeaderValueExtractor

func (HeaderValueExtractor) ExtractStringValue added in v0.0.6

func (e HeaderValueExtractor) ExtractStringValue(r *http.Request) (string, error)

type InvalidRequestError

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

func NewInvalidRequestError

func NewInvalidRequestError(fromError error) *InvalidRequestError

func (*InvalidRequestError) Error

func (e *InvalidRequestError) Error() string

func (*InvalidRequestError) HyperTextStatusCode

func (e *InvalidRequestError) HyperTextStatusCode() int

func (*InvalidRequestError) Unwrap

func (e *InvalidRequestError) Unwrap() error

type NullaryFuncAdaptor

type NullaryFuncAdaptor[O any] struct {
	// contains filtered or unexported fields
}

func NewNullaryFuncAdaptor

func NewNullaryFuncAdaptor[O any](
	domainCall func(context.Context) (O, error),
	withOptions ...Option,
) (*NullaryFuncAdaptor[O], error)

func (*NullaryFuncAdaptor[O]) ServeHTTP

func (a *NullaryFuncAdaptor[O]) ServeHTTP(
	w http.ResponseWriter,
	r *http.Request,
)

func (*NullaryFuncAdaptor[O]) ServeHyperText

func (a *NullaryFuncAdaptor[O]) ServeHyperText(
	w http.ResponseWriter,
	r *http.Request,
) (err error)

type Option

type Option func(*options) error

func WithCookieValues added in v0.0.6

func WithCookieValues(names ...string) Option

func WithDecoder

func WithDecoder(d Decoder) Option

func WithDecoderOptions

func WithDecoderOptions(withOptions ...reflectd.Option) Option

func WithDefaultDecoder

func WithDefaultDecoder() Option

func WithDefaultEncoder

func WithDefaultEncoder() Option

func WithDefaultResponseHandler added in v0.0.9

func WithDefaultResponseHandler() Option

func WithEncoder

func WithEncoder(e Encoder) Option

func WithEncoderFunc

func WithEncoderFunc(f func(http.ResponseWriter, any) error) Option

func WithExtractors added in v0.0.4

func WithExtractors(exs ...reflectd.RequestValueExtractor) Option

func WithHeaderValues added in v0.0.4

func WithHeaderValues(names ...string) Option

func WithHyperTextEncoder

func WithHyperTextEncoder(t *template.Template) Option

func WithMemoryLimit added in v0.0.4

func WithMemoryLimit(upto int64) Option

func WithOptions

func WithOptions(withOptions ...Option) Option

func WithPathValues added in v0.0.4

func WithPathValues(names ...string) Option

func WithQueryValues added in v0.0.4

func WithQueryValues(names ...string) Option

func WithReadLimit added in v0.0.4

func WithReadLimit(upto int64) Option

func WithResponseHandler added in v0.0.9

func WithResponseHandler(h ResponseHandler) Option

type PathValueExtractor added in v0.0.6

type PathValueExtractor string

func NewPathValueExtractor added in v0.0.6

func NewPathValueExtractor(name string) PathValueExtractor

func (PathValueExtractor) ExtractStringValue added in v0.0.6

func (e PathValueExtractor) ExtractStringValue(r *http.Request) (string, error)

type QueryValueExtractor added in v0.0.4

type QueryValueExtractor string

func NewQueryValueExtractor added in v0.0.4

func NewQueryValueExtractor(name string) QueryValueExtractor

func (QueryValueExtractor) ExtractStringValue added in v0.0.6

func (e QueryValueExtractor) ExtractStringValue(r *http.Request) (value string, err error)

type ResponseHandler added in v0.0.9

type ResponseHandler interface {
	HandleSuccess(http.ResponseWriter, *http.Request) error
	HandleError(http.ResponseWriter, *http.Request, error)
}

type StringValueExtractor added in v0.0.6

type StringValueExtractor interface {
	ExtractStringValue(*http.Request) (string, error)
}

type StringValueExtractorFunc added in v0.0.6

type StringValueExtractorFunc func(*http.Request) (string, error)

func (StringValueExtractorFunc) ExtractStringValue added in v0.0.6

func (f StringValueExtractorFunc) ExtractStringValue(r *http.Request) (string, error)

type UnaryFuncAdaptor

type UnaryFuncAdaptor[
	T any,
	V Validatable[T],
	O any,
] struct {
	// contains filtered or unexported fields
}

func NewUnaryFuncAdaptor

func NewUnaryFuncAdaptor[
	T any,
	V Validatable[T],
	O any,
](
	domainCall func(context.Context, V) (O, error),
	withOptions ...Option,
) (*UnaryFuncAdaptor[T, V, O], error)

func (*UnaryFuncAdaptor[T, V, O]) ServeHTTP

func (a *UnaryFuncAdaptor[T, V, O]) ServeHTTP(
	w http.ResponseWriter,
	r *http.Request,
)

func (*UnaryFuncAdaptor[T, V, O]) ServeHyperText

func (a *UnaryFuncAdaptor[T, V, O]) ServeHyperText(
	w http.ResponseWriter,
	r *http.Request,
) (err error)

type UnaryStringFuncAdaptor added in v0.0.2

type UnaryStringFuncAdaptor[O any] struct {
	// contains filtered or unexported fields
}

func NewUnaryStringFuncAdaptor added in v0.0.2

func NewUnaryStringFuncAdaptor[O any](
	domainCall func(context.Context, string) (O, error),
	stringExtractor StringValueExtractor,
	withOptions ...Option,
) (*UnaryStringFuncAdaptor[O], error)

func (*UnaryStringFuncAdaptor[O]) ServeHTTP added in v0.0.2

func (a *UnaryStringFuncAdaptor[O]) ServeHTTP(
	w http.ResponseWriter,
	r *http.Request,
)

func (*UnaryStringFuncAdaptor[O]) ServeHyperText added in v0.0.2

func (a *UnaryStringFuncAdaptor[O]) ServeHyperText(
	w http.ResponseWriter,
	r *http.Request,
) (err error)

type Validatable

type Validatable[T any] interface {
	*T
	Validate() error
}

Validatable constrains a domain request. Validation errors are wrapped as InvalidRequestError by the adapter.

type VoidFuncAdaptor

type VoidFuncAdaptor[
	T any,
	V Validatable[T],
] struct {
	// contains filtered or unexported fields
}

func NewVoidFuncAdaptor

func NewVoidFuncAdaptor[
	T any,
	V Validatable[T],
](
	domainCall func(context.Context, V) error,
	withOptions ...Option,
) (*VoidFuncAdaptor[T, V], error)

func (*VoidFuncAdaptor[T, V]) ServeHTTP

func (a *VoidFuncAdaptor[T, V]) ServeHTTP(
	w http.ResponseWriter,
	r *http.Request,
)

func (*VoidFuncAdaptor[T, V]) ServeHyperText

func (a *VoidFuncAdaptor[T, V]) ServeHyperText(
	w http.ResponseWriter,
	r *http.Request,
) (err error)

type VoidStringFuncAdaptor added in v0.0.2

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

func NewVoidStringFuncAdaptor added in v0.0.2

func NewVoidStringFuncAdaptor(
	domainCall func(context.Context, string) error,
	stringExtractor StringValueExtractor,
	withOptions ...Option,
) (*VoidStringFuncAdaptor, error)

func (*VoidStringFuncAdaptor) ServeHTTP added in v0.0.2

func (a *VoidStringFuncAdaptor) ServeHTTP(
	w http.ResponseWriter,
	r *http.Request,
)

func (*VoidStringFuncAdaptor) ServeHyperText added in v0.0.2

func (a *VoidStringFuncAdaptor) ServeHyperText(
	w http.ResponseWriter,
	r *http.Request,
) (err error)

Directories

Path Synopsis
chivalues module
examples
basic
Package main demonstrates application of generic domain adaptors to satisfy [http.Handler] interface.
Package main demonstrates application of generic domain adaptors to satisfy [http.Handler] interface.
extract
chivalues Module
Package reflectd provides configurable HTTP form body to struct decoder that depends on Gorilla's schema reflection package.
Package reflectd provides configurable HTTP form body to struct decoder that depends on Gorilla's schema reflection package.
schema
Package schema fills a struct with form values.
Package schema fills a struct with form values.
Package slogrh handles domain logic reponses by logging them using [slog.Logger] and printing a simple error message.
Package slogrh handles domain logic reponses by logging them using [slog.Logger] and printing a simple error message.
TODO: move this into root package.
TODO: move this into root package.

Jump to

Keyboard shortcuts

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