yam

package module
v0.0.0-...-892de57 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2015 License: MIT Imports: 4 Imported by: 0

README

YAM

Build Status Coverage Docs Licsense

YAM (Yet Another Mux) is another Golang HTTP multiplexer designed to be simple, flexible and configurable.

package main

import (
	"net/http"

	"github.com/thisissoon/yam"
)

func main() {
	mux := yam.New()
	mux.Route("/").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello World!"))
	}))

	http.ListenAndServe(":5000", mux)
}

Install

go get github.com/thisissoon/yam

Documentaion

Full package documentation can be found at https://godoc.org/github.com/thisissoon/yam.

Documentation

Overview

YAM (Yet Another Mux) is a simple HTTP Multiplexer (Router).

Overview

YAM's goal is to be simple, flexible and configurable. Above all it does break the standard interfaces and function handlers of the net/http package.

This is YAM's most simplest implementation:

mux := yam.New()
mux.Route("/").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World"))
})
http.ListenAndServe(":5000", mux)

Features

Yam has the following features:

  • Method based routing, returning 405 when a route does not implement a specific verb
  • Simple pattern matching using the "/foo/:bar/baz" syntax, values are placed onto the request URL parameters
  • Support for all the standard HTTP verbs out of the box (OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE)
  • Sub Routing
  • Configuration, allowing default handler functions overrides and flags for OPTIONS and TRACE

Method Based Routing

To implement a method on a route simple call the routes method function for that method:

mux := yam.New()
mux.Route("/").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get Request"))
})
mux.Route("/").Post(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Post Request"))
})
http.ListenAndServe(":5000", mux)

In the above example only "GET" and "POST" are supported, other methods such as "PUT" would return a "405 Method Not Allowed".

Middleare

You can apply middlware globaly to all the routes or on a route by route basis.

func GlobalMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("GobalMiddlware", "True")
		next.ServeHTTP(w, r)
	})
}

func RouteOnly(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("RouteOnly", "True")
		next.ServeHTTP(w, r)
	})
}

func main() {
	mux := yam.New()
	mux.Route("/").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello World!"))
	}))

	mux.Route("/foo").Get(RouteOnly(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello World!"))
	})))

	http.ListenAndServe(":5000", GlobalMiddleware(mux))
}

Pattern Matching

YAM implements a very simple "/foo/:bar" pattern matching system, values from those patterns are placed on the requests URL as query parameters and therefore no extra dependencies are required. The values persist down the path.

mux := yam.New()
mux.Route("/foo/:bar").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(r.URL.Query().Get(":bar")))
})
mux.Route("/foo/:bar/baz/:fiz").Get(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(r.URL.Query().Get(":bar")+"\n"))
	w.Write([]byte(r.URL.Query().Get(":fix")+"\n"))
})

http.ListenAndServe(":5000", mux)

Methods

YAM supports all the standard HTTP verbs, with the exception of CONNECT (https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods). Each verb has it's own function on a specific route, if the route does not implement a verb and a request is made with that verb a 405 will be returned.

mux := yam.New()
mux.Route("/foo").
	Get(get).
	Post(post).
	Put(put).
	Patch(patch).
	Delete(delete)
http.ListenAndServe(":5000", mux)

In the case of "OPTIONS" and "HEAD" these are handled for you provided YAM is configured to do (which it is by default).

The default "OPTIONS" handler function will add an "Allow" header which will be populated with the verbs supported by the route. This behaviour can be turned off or overridden on a route by route basis:

mux := yam.New()
mux.Route("/foo").Get(myGetHandler).Options(myOptionsHandler)

The default "HEAD" handler will only be implemented for the route if a Get handler has been added. This will simply return the Headers for a response minus a response body, this behaviour can be turned off or overridden for specific routes:

mux := yam.New()
mux.Route("/foo").Get(myGetHandler).Head(myHeadHandler)

The "TRACE" verb is disabled by default but is useful for debugging purposes, to enable it alter YAM's configuration:

mux := yam.New()
mux.Config.Trace = true
mux.Route("/foo").Get(myGetHandler)

You can also enable "TRACE" on a route by route basis:

mux := yam.New()
mux.Route("/foo").Trace(yam.DefaultTraceHandler)
mux.Route("/bar").Trace(myTraceHandler)

You can also use the "Add" function:

mux := yam.New()
mux.Route("/foo").Add("VERB", http.Handler)

Sub Routing

Routes can also be broken up to avoid repetition and broken up across packages.

mux := yam.New()
foo := mux.Route("/foo").Get(myGetHandler)
bar := foo.Route("/bar").Post(myPostHandler).Delete(myDeleteHandler)
bar.Route("/baz").Put(myPutHandler)

The above would register the following routes.

GET /foo
POST & DELETE /foo/bar
PUT /foo/bar/baz

Configuration

Finally if you do not like any of the default settings of "YAM", you can change them! The Config type allows this:

mux := yam.New()
config := NewConfig() // Defaults
config.Options = false // OPTIONS will no longer be supported on all routes
config.OptionsHandler = func(r *yam.Route) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("My-Custom-Header", "Foo")
	})
} // Set a custom OPTIONS handler used when config.Options is true
config.Trace = true // TRACE will now be supported on all routes
config.TraceHandler = func(r *yam.Route) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		dump, _ := httputil.DumpRequest(r, false)
		w.Write(dump)
	})
} // Set a custom handler function for TRACE when config.Trace is true
config.AddHeadOnGet = false // HEAD support will not longer be added by default on Get
mux.Config = config

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultOptionsHandler

func DefaultOptionsHandler(route *Route) http.Handler

Default HTTP Handler function for OPTIONS requests. Adds the Allow header with the http verbs the route supports

func DefaultTraceHandler

func DefaultTraceHandler(route *Route) http.Handler

Default HTTP handler function for TRACE requests. Dumps the request as the Response.

Types

type Config

type Config struct {
	Options        bool
	OptionsHandler func(*Route) http.Handler
	Trace          bool
	TraceHandler   func(*Route) http.Handler
	AddHeadOnGet   bool
}

Configuration type that allows configuration of YAM

func NewConfig

func NewConfig() *Config

Constructs a new Config instance with default values

type Route

type Route struct {
	Routes []*Route // Routes that live under this route
	// contains filtered or unexported fields
}

This type contains all the handlers for each path, each Route can also hold a list of child routes

func (*Route) Add

func (r *Route) Add(method string, h http.Handler) *Route

Adds a new handler to the route based on http Verb

func (*Route) Delete

func (r *Route) Delete(h http.Handler) *Route

Set a DELETE request handler for the route.

func (*Route) Get

func (r *Route) Get(h http.Handler) *Route

Set a GET request handler for the Route. A default HEAD request implementation will also be implemented since HEAD requests should perform the same as a GET request but simply not return the response body.

func (*Route) Head

func (r *Route) Head(h http.Handler) *Route

Set a HEAD request handler for the route

func (*Route) Options

func (r *Route) Options(h http.Handler) *Route

Set a OPTIONS request for the route, overrides default implementation

func (*Route) Patch

func (r *Route) Patch(h http.Handler) *Route

Set a PATCH request handler for the route.

func (*Route) Post

func (r *Route) Post(h http.Handler) *Route

Set a POST request handler for the route.

func (*Route) Put

func (r *Route) Put(h http.Handler) *Route

Set a PUT request handler for the route.

func (*Route) Route

func (r *Route) Route(path string) *Route

Adds a new route to the tree, and depending on configuration implements default handler implementation for OPTIONS and TRACE requests

func (*Route) Trace

func (r *Route) Trace(h http.Handler) *Route

Set a TRACE request for the route, overrides default implementation

type Yam

type Yam struct {
	Root   *Route
	Config *Config
}

Base YAM type contain the Root Routes and Configuration

func New

func New() *Yam

Constructs a new YAM instance with default configuration

func (*Yam) Route

func (y *Yam) Route(path string) *Route

Creates a new base Route - Effectively a constructor for Route

func (*Yam) ServeHTTP

func (y *Yam) ServeHTTP(w http.ResponseWriter, r *http.Request)

Implements the http.Handler Interface. Finds the correct handler for a path based on the path and http verb of the request.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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