rf

package module
v0.0.0-...-8f77053 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2022 License: MIT Imports: 1 Imported by: 0

README

rf

Request Framework - rf is a very light set of interfaces and handler types that I've used on personal projects. After building a few things with the same pieces of code strewn around I decided to standardise the request/response patterns.

Everything works with Go's net/http directly, meaning you can bring your own middleware, use Chi or http.Mux! You can rework middleware to gain advantage of error handling (see middleware folder) within rf.

There are two main handlers for requests:

  • RPC (POST, json + jsonschema, snicol/yael for errors)
  • Basic (GET params and/or POST forms)

All requests types can happily live in harmony together under the same mux/router. This allows for things such as OAuth2 services to be built with RPC methods along with the required GET requests as per spec.

Examples

See example/{basic,rpc} for the best examples of how each type works.

Basic usage
func main() {
    // creates a handler group which will apply a default stack of middleware
    g := rf.NewHandlerGroup(rpc.DefaultMiddleware(), middleware.Logger(logger))

    // RPC:
    // wrap the Example handler func (see below example) with a schema loaded using
    // gojsonschema.NewStringLoader/NewBytesLoader/etc, using the group we
    // just created
    http.Handle("/example", g.Use(rpc.NewHandler(Example, schema)))

    // pass in extra middleware per handler:
    http.Handle("/example", g.Use(rpc.NewHandler(Example, schema), MyCustomMiddleware, AnotherMiddleware, ...etc))

    // Basic: same applies
    http.Handle("/example_get", g.Use(basic.NewHandler(basic.GetParams, Example), MyCustomMiddleware))
    http.Handle("/example_post", g.Use(basic.NewHandler(basic.PostForm, Example), MyCustomMiddleware))

    // listen!
    http.ListenAndServe(":8000")
}
RPC handlers

Function signatures are like so:

func Example(ctx context.Context, req *SomeInputType) (*YourOutput, error)

Input is validated using jsonschema.

Basic handlers

Basic requests can handle either GET params or POST forms with the same signature:

func Handler(ctx context.Context, req *SomeInputType) (*basic.Response, error)

The request input from either params or form data is decoded into SomeInputType using gorilla/schema, therefore all fields need to have the correct struct tags.

They differ slightly from RPC requests in that the response must be of type *basic.Response. This type has the following fields:

  • Body (string)
  • StatusCode (int)
  • Headers (map[string]string)

All of these are optional, but once set will return the correct response to the client.

If no status code is set, it default to 200. If no headers are set, it default to Content-Type: text/plain only.

Notes

The next things that I will be adding are tests, a few more useful middlewares (including moving shared logic from handlers into middleware). A lot more of the code will be commented when it's more concrete.

I will continue to chop and change features over time as my personal projects evolve. There are no safety or security guarantees with this software!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrorHandlerFunc

type ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)

ErrorHandlerFunc is the error handler function definition which is used in the Handler interface. All custom handlers must return a func of this type to handle errors

type Handler

type Handler interface {
	Handle() HandlerFunc
	Error() ErrorHandlerFunc
}

Handler is the primary interface of this package - it defines the two standard functions to implement custom handler types

type HandlerFunc

type HandlerFunc func(w http.ResponseWriter, r *http.Request) error

HandlerFunc defines the standard handler function type, used in the Handler interface. All custom handlers must return a func of this type to handle requests

type HandlerGroup

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

HandlerGroup holds middleware and is intended to group handlers of the same request type so that the same middleware stack can be applied

func NewHandlerGroup

func NewHandlerGroup(mws []MiddlewareFunc, more ...MiddlewareFunc) *HandlerGroup

NewHandlerGroup returns an instance of HandlerGroup with the middlware functions attached

func (*HandlerGroup) Use

func (hs *HandlerGroup) Use(h Handler, mws ...MiddlewareFunc) http.HandlerFunc

Use returns a http.Handler func, wrapped with middlewares which the request will be handled by the given rf.Handler

type MiddlewareFunc

type MiddlewareFunc func(next HandlerFunc) HandlerFunc

MiddlewareFunc is the type used for all rf specific middleware

Directories

Path Synopsis
example
rpc

Jump to

Keyboard shortcuts

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