router

package module
v0.6.5 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2017 License: BSD-3-Clause Imports: 8 Imported by: 28

README

Go Router

Build Status GoDoc Contributions Welcome Go Report Card codecov.io

A simple, compact and fast router package to process HTTP requests. It has some sugar from framework however still lightweight. The router package is useful to prepare a RESTful API for Go services. It has JSON output, which bind automatically for relevant type of data. The router has timer feature to display duration of request handling in the header

Examples
  • Simplest example (serve static route):
package main

import (
	"github.com/takama/router"
)

func Hello(c *router.Control) {
	c.Body("Hello world")
}

func main() {
	r := router.New()
	r.GET("/hello", Hello)

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i http://localhost:8888/hello/

HTTP/1.1 200 OK
Content-Type: text/plain
Date: Sun, 17 Aug 2014 13:25:50 GMT
Content-Length: 11

Hello world
  • Serve dynamic route with parameter:
package main

import (
	"github.com/takama/router"
)

func main() {
	r := router.New()
	r.GET("/hello/:name", func(c *router.Control) {
		c.Body("Hello " + c.Get(":name"))
	})

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i http://localhost:8888/hello/John

HTTP/1.1 200 OK
Content-Type: text/plain
Date: Sun, 17 Aug 2014 13:25:55 GMT
Content-Length: 10

Hello John
  • Checks JSON Content-Type automatically:
package main

import (
	"github.com/takama/router"
)

// Data is helper to construct JSON
type Data map[string]interface{}

func main() {
	r := router.New()
	r.GET("/api/v1/settings/database/:db", func(c *router.Control) {
		data := Data{
			"Database settings": Data{
				"database": c.Get(":db"),
				"host":     "localhost",
				"port":     "3306",
			},
		}
		c.Code(200).Body(data)
	})
	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i http://localhost:8888/api/v1/settings/database/testdb

HTTP/1.1 200 OK
Content-Type: application/json
Date: Sun, 17 Aug 2014 13:25:58 GMT
Content-Length: 102

{
  "Database settings": {
    "database": "testdb",
    "host": "localhost",
    "port": "3306"
  }
}
  • Use timer to calculate duration of request handling:
package main

import (
	"github.com/takama/router"
)

// Data is helper to construct JSON
type Data map[string]interface{}

func main() {
	r := router.New()
	r.GET("/api/v1/settings/database/:db", func(c *router.Control) {
		c.UseTimer()

		// Do something

		data := Data{
			"Database settings": Data{
				"database": c.Get(":db"),
				"host":     "localhost",
				"port":     "3306",
			},
		}
		c.Code(200).Body(data)
	})
	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i http://localhost:8888/api/v1/settings/database/testdb

HTTP/1.1 200 OK
Content-Type: application/json
Date: Sun, 17 Aug 2014 13:26:05 GMT
Content-Length: 143

{
  "duration": 5356123
  "took": "5.356ms",
  "data": {
    "Database settings": {
      "database": "testdb",
      "host": "localhost",
      "port": "3306"
    }
  }
}
  • Custom handler with "Access-Control-Allow" options and compact JSON:
package main

import (
	"github.com/takama/router"
)

// Data is helper to construct JSON
type Data map[string]interface{}

func baseHandler(handle router.Handle) router.Handle {
	return func(c *router.Control) {
		c.CompactJSON(true)
		if origin := c.Request.Header.Get("Origin"); origin != "" {
			c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
			c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		}
		handle(c)
	}
}

func Info(c *router.Control) {
	data := Data{
		"debug": true,
		"error": false,
	}
	c.Body(data)
}

func main() {
	r := router.New()
	r.CustomHandler = baseHandler
	r.GET("/info", Info)

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i -H 'Origin: http://foo.com' http://localhost:8888/info/

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://foo.com
Content-Type: text/plain
Date: Sun, 17 Aug 2014 13:27:10 GMT
Content-Length: 28

{"debug":true,"error":false}
  • Use google json style https://google.github.io/styleguide/jsoncstyleguide.xml:
package main

import (
	"net/http"

	"github.com/takama/router"
)

func main() {
	r := router.New()
	r.GET("/api/v1/people/:action/:id", func(c *router.Control) {

		// Do something

		c.Method("people." + c.Get(":action"))
		c.SetParams(map[string]string{"userId": c.Get(":id")})
		c.SetError(http.StatusNotFound, "UserId not found")
		c.AddError(router.Error{Message: "Group or User not found"})
		c.Code(http.StatusNotFound).Body(nil)
	})
	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}
  • Check it:
curl -i http://localhost:8888/api/v1/people/get/@me

HTTP/1.1 404 Not Found
Content-Type: application/json
Date: Sat, 22 Oct 2016 14:50:00 GMT
Content-Length: 220

{
  "method": "people.get",
  "params": {
    "userId": "@me"
  },
  "error": {
    "code": 404,
    "message": "UserId not found",
    "errors": [
      {
        "message": "Group or User not found"
      }
    ]
  }
}

Contributors (unsorted)

All the contributors are welcome. If you would like to be the contributor please accept some rules.

  • The pull requests will be accepted only in "develop" branch
  • All modifications or additions should be tested
  • Sorry, I'll not accept code with any dependency, only standard library

Thank you for your understanding!

License

BSD License

Documentation

Overview

Package router 0.6.5 provides fast HTTP request router.

The router matches incoming requests by the request method and the path. If a handle is registered for this path and method, the router delegates the request to defined handler. The router package is useful to prepare a RESTful API for Go services. It has JSON output, which bind automatically for relevant type of data. The router has timer feature to display duration of request handling in the header

Simplest example (serve static route):

package main

import (
	"github.com/takama/router"
)

func Hello(c *router.Control) {
	c.Body("Hello")
}

func main() {
	r := router.New()
	r.GET("/hello", Hello)

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}

Check it:

curl -i http://localhost:8888/hello

Serve dynamic route with parameter:

func main() {
	r := router.New()
	r.GET("/hello/:name", func(c *router.Control) {
		c.Code(200).Body("Hello " + c.Get(":name"))
	})

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}

Checks JSON Content-Type automatically:

// Data is helper to construct JSON
type Data map[string]interface{}

func main() {
	r := router.New()
	r.GET("/settings/database/:db", func(c *router.Control) {
		data := map[string]map[string]string{
			"Database settings": {
				"database": c.Get(":db"),
				"host":     "localhost",
				"port":     "3306",
			},
		}
		c.Code(200).Body(data)
	})
	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}

Custom handler with "Access-Control-Allow" options and compact JSON:

// Data is helper to construct JSON
type Data map[string]interface{}

func baseHandler(handle router.Handle) router.Handle {
	return func(c *router.Control) {
		c.CompactJSON(true)
		if origin := c.Request.Header.Get("Origin"); origin != "" {
			c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
			c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		}
		handle(c)
	}
}

func Info(c *router.Control) {
	data := Data{
		"debug": true,
		"error": false,
	}
	c.Body(data)
}

func main() {
	r := router.New()
	r.CustomHandler = baseHandler
	r.GET("/info", Info)

	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}

Use google json style `https://google.github.io/styleguide/jsoncstyleguide.xml`

func main() {
	r := router.New()
	r.GET("/api/v1/people/:action/:id", func(c *router.Control) {

		// Do something

		c.Method("people." + c.Get(":action"))
		c.SetParams(map[string]string{"userId": c.Get(":id")})
		c.SetError(http.StatusNotFound, "UserId not found")
		c.AddError(router.Error{Message: "Group or User not found"})
		c.Code(http.StatusNotFound).Body(nil)
	})
	// Listen and serve on 0.0.0.0:8888
	r.Listen(":8888")
}

Go Router

Index

Constants

View Source
const (
	// MIMEJSON - "Content-type" for JSON
	MIMEJSON = "application/json"
	// MIMETEXT - "Content-type" for TEXT
	MIMETEXT = "text/plain"
)

Default content types

Variables

This section is empty.

Functions

This section is empty.

Types

type Control

type Control struct {

	// Context embedded
	context.Context

	// Request is an adapter which allows the usage of a http.Request as standard request
	Request *http.Request

	// Writer is an adapter which allows the usage of a http.ResponseWriter as standard writer
	Writer http.ResponseWriter

	// User content type
	ContentType string
	// contains filtered or unexported fields
}

Control allows us to pass variables between middleware, assign Http codes and render a Body.

func (*Control) APIVersion

func (c *Control) APIVersion(version string) *Control

APIVersion adds API version meta data

func (*Control) AddError

func (c *Control) AddError(errors ...Error) *Control

AddError adds new error

func (*Control) Body

func (c *Control) Body(data interface{})

Body renders the given data into the response body

func (*Control) Code

func (c *Control) Code(code int) *Control

Code assigns http status code, which returns on http request

func (*Control) CompactJSON

func (c *Control) CompactJSON(mode bool) *Control

CompactJSON changes JSON output format (default mode is false)

func (*Control) Get

func (c *Control) Get(name string) string

Get returns the first value associated with the given name. If there are no values associated with the key, an empty string is returned.

func (*Control) GetCode

func (c *Control) GetCode() int

GetCode returns status code

func (*Control) GetTimer

func (c *Control) GetTimer() time.Time

GetTimer returns timer state

func (*Control) HeaderContext

func (c *Control) HeaderContext(context string) *Control

HeaderContext adds context meta data

func (*Control) ID

func (c *Control) ID(id string) *Control

ID adds id meta data

func (*Control) Method

func (c *Control) Method(method string) *Control

Method adds method meta data

func (*Control) Set

func (c *Control) Set(params ...Param) *Control

Set adds new parameters which represents as set of key/value.

func (*Control) SetError

func (c *Control) SetError(code uint16, message string) *Control

SetError sets error code and error message

func (*Control) SetParams

func (c *Control) SetParams(params interface{}) *Control

SetParams adds params meta data in alternative format

func (*Control) UseMetaData

func (c *Control) UseMetaData() *Control

UseMetaData shows meta data in JSON Header

func (*Control) UseTimer

func (c *Control) UseTimer()

UseTimer allows caalculate elapsed time of request handling

type Error

type Error struct {
	Domain       string `json:"domain,omitempty"`
	Reason       string `json:"reason,omitempty"`
	Message      string `json:"message,omitempty"`
	Location     string `json:"location,omitempty"`
	LocationType string `json:"locationType,omitempty"`
	ExtendedHelp string `json:"extendedHelp,omitempty"`
	SendReport   string `json:"sendReport,omitempty"`
}

Error report format

type ErrorHeader

type ErrorHeader struct {
	Code    uint16  `json:"code,omitempty"`
	Message string  `json:"message,omitempty"`
	Errors  []Error `json:"errors,omitempty"`
}

ErrorHeader contains error code, message and array of specified error reports

type Handle

type Handle func(*Control)

Handle type is aliased to type of handler function.

type Header struct {
	Duration   time.Duration `json:"duration,omitempty"`
	Took       string        `json:"took,omitempty"`
	APIVersion string        `json:"apiVersion,omitempty"`
	Context    string        `json:"context,omitempty"`
	ID         string        `json:"id,omitempty"`
	Method     string        `json:"method,omitempty"`
	Params     interface{}   `json:"params,omitempty"`
	Data       interface{}   `json:"data,omitempty"`
	Error      interface{}   `json:"error,omitempty"`
}

Header is used to prepare a JSON header with meta data

type Param

type Param struct {
	Key   string `json:"key,omitempty"`
	Value string `json:"value,omitempty"`
}

Param is a URL parameter which represents as key and value.

type Route

type Route struct {
	Method string
	Path   string
}

Route type contains information about HTTP method and path

type Router

type Router struct {

	// NotFound is called when unknown HTTP method or a handler not found.
	// If it is not set, http.NotFound is used.
	// Please overwrite this if need your own NotFound handler.
	NotFound Handle

	// PanicHandler is called when panic happen.
	// The handler prevents your server from crashing and should be used to return
	// http status code http.StatusInternalServerError (500)
	PanicHandler Handle

	// CustomHandler is called allways if defined
	CustomHandler func(Handle) Handle

	// Logger activates logging user function for each requests
	Logger Handle
	// contains filtered or unexported fields
}

Router represents a multiplexer for HTTP requests.

func New

func New() *Router

New it returns a new multiplexer (Router).

func (*Router) AllowedMethods

func (r *Router) AllowedMethods(path string) []string

AllowedMethods returns list of allowed methods

func (*Router) DELETE

func (r *Router) DELETE(path string, h Handle)

DELETE is a shortcut for Router Handle("DELETE", path, handle)

func (*Router) GET

func (r *Router) GET(path string, h Handle)

GET is a shortcut for Router Handle("GET", path, handle)

func (*Router) HEAD

func (r *Router) HEAD(path string, h Handle)

HEAD is a shortcut for Router Handle("HEAD", path, handle)

func (*Router) Handle

func (r *Router) Handle(method, path string, h Handle)

Handle registers a new request handle with the given path and method.

func (*Router) Handler

func (r *Router) Handler(method, path string, handler http.Handler)

Handler allows the usage of an http.Handler as a request handle.

func (*Router) HandlerFunc

func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)

HandlerFunc allows the usage of an http.HandlerFunc as a request handle.

func (*Router) Listen

func (r *Router) Listen(hostPort string)

Listen and serve on requested host and port.

func (*Router) Lookup

func (r *Router) Lookup(method, path string) (Handle, []Param, bool)

Lookup returns handler and URL parameters that associated with path.

func (*Router) OPTIONS

func (r *Router) OPTIONS(path string, h Handle)

OPTIONS is a shortcut for Router Handle("OPTIONS", path, handle)

func (*Router) PATCH

func (r *Router) PATCH(path string, handle Handle)

PATCH is a shortcut for router.Handle("PATCH", path, handle)

func (*Router) POST

func (r *Router) POST(path string, h Handle)

POST is a shortcut for Router Handle("POST", path, handle)

func (*Router) PUT

func (r *Router) PUT(path string, h Handle)

PUT is a shortcut for Router Handle("PUT", path, handle)

func (*Router) Routes

func (r *Router) Routes() []Route

Routes returns list of registered HTTP methods with path

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements http.Handler interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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