min

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Nov 14, 2018 License: MIT Imports: 4 Imported by: 1

README

min

v0.1.1

GoDoc Go Report Card Build Status Codecov GitHub

min is a BYO*, minimalistic web framework that harnesses the power of context and httprouter, and adds some functionality on top—namely, middleware chaining and route grouping. It's meant to be used on projects large and small that require flexibility, and varying degrees of custom code and architecture. min provides the routing, you provide the app.

This package takes some inspiration from design decisions in chi and gin.

Usage

min is designed to be as elegant and as close to "the right way to do things" as possible. Which means that it doesn't implement a lot of custom types, or does a lot of magic. It relies heavily on context and regular types from net/http.

Hello World

You can initialize a new instance of the Min type with an httprouter.Router you provide, or you can pass nil to min.New and a new, default router will be created.

import (
    "fmt"
    "net/http"

    "github.com/arturovm/min"
)

func main() {
    m := min.New(nil)

    m.Get("/", helloWorld)

    http.ListenAndServe(":8080", m)
}

func helloWorld(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "hello world!")
}
Route Parameters

min supports all the syntax variations for defining route parameters that httprouter does. You then simply use the helper function min.GetParam to access them.

import (
    "fmt"
    "net/http"

    "github.com/arturovm/min"
)

func main() {
    m := min.New(nil)

    m.Get("/:name", greet)

    http.ListenAndServe(":8080", m)
}

func greet(w http.ResponseWriter, r *http.Request) {
    name := min.GetParam(r, "name")
    fmt.Fprintf(w, "hello %s!", name)
}
Route Grouping
import (
    "fmt"
    "net/http"

    "github.com/arturovm/min"
)

func main() {
    m := min.New(nil)

    apiRouter := m.Group("/api")
    {
        // GET /api
        apiRouter.Get("/", apiRoot)
        // GET /api/ignacio
        apiRouter.Get("/:name", greet)
    }

    http.ListenAndServe(":8080", m)
}

func apiRoot(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "api root")
}

func greet(w http.ResponseWriter, r *http.Request) {
    name := min.GetParam(r, "name")
    fmt.Fprintf(w, "hello %s!", name)
}
Middleware

Middleware in min are simply functions that take an http.Handler (the one next in the chain) and return another one. They are resolved in the order that they are declared.

min users are meant to take advantage of context to make better use of middleware.

import (
    "context"
    "fmt"
    "log"
    "net/http"

    "github.com/arturovm/min"
)

func main() {
    m := min.New(nil)
    m.Use(logger)
    m.Use(printer)

    apiRouter := m.Group("/api")
    {
        apiRouter.Get("/", apiRoot)
        nameRouter := apiRouter.Group("/:name")
        {
            // Every request sent to routes defined on this sub-router will now
            // have a reference to a name in its context.
            // Useful for RESTful design.
            nameRouter.Use(nameExtractor)

            // GET /api/ignacio
            nameRouter.Get("/", greet)
            // GET /api/ignacio/goodbye
            nameRouter.Get("/goodbye", goodbye)
        }
    }

    http.ListenAndServe(":8080", m)
}

// -- Middleware --

// a simple logger
func logger(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("| %s %s", r.Method, r.URL)
        next.ServeHTTP(w, r)
    })
}

// a useless middleware that prints text
func printer(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("this prints some text")
        next.ServeHTTP(w, r)
    })
}

// extracts a name from the URL and injects it into the request's context
func nameExtractor(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        name := min.GetParam(r, "name")
        ctx := context.WithValue(r.Context(), "name", name)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

// -- Handlers --

func apiRoot(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "api root")
}

// greets the user with :name
func greet(w http.ResponseWriter, r *http.Request) {
    name := r.Context().Value("name").(string)
    fmt.Fprintf(w, "hello %s!", name)
}

// says "bye" to the user with :name
func goodbye(w http.ResponseWriter, r *http.Request) {
    name := r.Context().Value("name").(string)
    fmt.Fprintf(w, "bye %s!", name)
}
Base Router

If you need access to the underlying httprouter.Router, you can use the GetBaseRouter method.

import (
    "github.com/arturovm/min"
)

func main() {
    m := min.New(nil)

    _ = m.GetBaseRouter()
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetParam

func GetParam(r *http.Request, key string) string

GetParam gets a parameter from a given request

Types

type Groupable

type Groupable interface {
	Group(string) Router
}

Groupable enables route composition

type Handler

type Handler interface {
	Post(string, http.HandlerFunc)
	Get(string, http.HandlerFunc)
	Put(string, http.HandlerFunc)
	Patch(string, http.HandlerFunc)
	Delete(string, http.HandlerFunc)
	Head(string, http.HandlerFunc)
	Options(string, http.HandlerFunc)
}

Handler represents anything that can be used to register routes

type Min

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

Min is the main type. It contains an httprouter.Router, and wraps around it to provide extra functionality.

func New

func New(router *httprouter.Router) *Min

New returns a new Min with the provided httprouter.Router as the base router. If router is nil, a new, default one is created.

func (*Min) Delete

func (m *Min) Delete(path string, handler http.HandlerFunc)

Delete registers a handler for DELETE requests

func (*Min) Get

func (m *Min) Get(path string, handler http.HandlerFunc)

Get registers a handler for GET requests

func (*Min) GetBaseRouter

func (m *Min) GetBaseRouter() *httprouter.Router

GetBaseRouter returns a pointer to the contained httprouter.Router, which enables users to change and configure the router as they please

func (*Min) Group

func (m *Min) Group(root string) Router

Group defines a route group on top of the root router

func (*Min) Head

func (m *Min) Head(path string, handler http.HandlerFunc)

Head registers a handler for HEAD requests

func (*Min) Options

func (m *Min) Options(path string, handler http.HandlerFunc)

Options registers a handler for OPTIONS requests

func (*Min) Patch

func (m *Min) Patch(path string, handler http.HandlerFunc)

Patch registers a handler for PATCH requests

func (*Min) Post

func (m *Min) Post(path string, handler http.HandlerFunc)

Post registers a handler for POST requests

func (*Min) Put

func (m *Min) Put(path string, handler http.HandlerFunc)

Put registers a handler for PUT requests

func (*Min) ServeHTTP

func (m *Min) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Min) Use

func (m *Min) Use(f func(http.Handler) http.Handler)

Use adds a middleware to the global middleware chain

type Pluggable

type Pluggable interface {
	Use(func(http.Handler) http.Handler)
}

Pluggable allows for middleware usage

type Router

type Router interface {
	Groupable
	Handler
	Pluggable
	http.Handler
}

Router implements the groupable, handler, pluggable and http.Handler interfaces

Jump to

Keyboard shortcuts

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