• Stars
    star
    149
  • Rank 248,567 (Top 5 %)
  • Language
    Go
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🚱 Is a lightweight HTTP router that sticks to the std "net/http" implementation

package pure

Project status Build Status Coverage Status Go Report Card GoDoc License Gitter

Pure is a fast radix-tree based HTTP router that sticks to the native implementations of Go's "net/http" package; in essence, keeping the handler implementations 'pure' by using Go 1.7's "context" package.

This makes heavy usage of github.com/go-playground/pkg/v5 for HTTP abstractions.

Why Another HTTP Router?

I initially created lars, which I still maintain, that wraps the native implementation, think of this package as a Go pure implementation of lars

Key & Unique Features

  • It sticks to Go's native implementations while providing helper functions for convenience
  • Fast & Efficient - pure uses a custom version of httprouter's radix tree, so incredibly fast and efficient.

Installation

Use go get

go get -u github.com/go-playground/pure/v5

Usage

package main

import (
	"net/http"

	"github.com/go-playground/pure/v5"
	mw "github.com/go-playground/pure/v5/_examples/middleware/logging-recovery"
)

func main() {

	p := pure.New()
	p.Use(mw.LoggingAndRecovery(true))

	p.Get("/", helloWorld)

	http.ListenAndServe(":3007", p.Serve())
}

func helloWorld(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World"))
}

RequestVars

This is an interface that is used to pass request scoped variables and functions using context.Context. It is implemented in this way because retrieving values from context isn't the fastest, and so using this the router can store multiple pieces of information while reducing lookup time to a single stored RequestVars.

Currently only the URL/SEO params are stored on the RequestVars but if/when more is added they can merely be added to the RequestVars and there will be no additional lookup time.

URL Params

p := p.New()

// the matching param will be stored in the context's params with name "id"
p.Get("/user/:id", UserHandler)

// extract params like so
rv := pure.RequestVars(r) // done this way so only have to extract from context once, read above
rv.URLParam(paramname)

// serve css, js etc.. pure.RequestVars(r).URLParam(pure.WildcardParam) will return the remaining path if 
// you need to use it in a custom handler...
p.Get("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))).ServeHTTP)

...

Note: Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns /user/new and /user/:user for the same request method at the same time. The routing of different request methods is independent from each other. I was initially against this, however it nearly cost me in a large web application where the dynamic param value say :type actually could have matched another static route and that's just too dangerous and so it is not allowed.

Groups

p.Use(LoggingAndRecovery, Gzip...)
...
p.Post("/users/add", ...)

// creates a group for /user/:userid + inherits all middleware registered previously by p
user := p.Group("/user/:userid")
user.Get("", ...)
user.Post("", ...)
user.Delete("/delete", ...)

contactInfo := user.Group("/contact-info/:cid")
contactinfo.Delete("/delete", ...)

// creates a group for /others, inherits all middleware registered previously by p + adds 
// OtherHandler to middleware
others := p.GroupWithMore("/others", OtherHandler)

// creates a group for /admin WITH NO MIDDLEWARE... more can be added using admin.Use()
admin := p.GroupWithNone("/admin")
admin.Use(SomeAdminSecurityMiddleware)
...

Decoding Body

currently JSON, XML, FORM, Multipart Form and url.Values are support out of the box; there are also individual functions for each as well when you know the Content-Type.

	// second argument denotes yes or no I would like URL query parameter fields
	// to be included. i.e. 'id' and 'id2' in route '/user/:id?id2=val' should it be included.
	if err := pure.Decode(r, true, maxBytes, &user); err != nil {
		log.Println(err)
	}

Misc

// set custom 404 ( not Found ) handler
p.Register404(404Handler, middleware_like_logging)

// Redirect to or from ending slash if route not found, default is true
p.SetRedirectTrailingSlash(true)

// Handle 405 ( Method Not allowed ), default is false
p.RegisterMethodNotAllowed(middleware)

// automatically handle OPTION requests; manually configured
// OPTION handlers take precedence. default false
p.RegisterAutomaticOPTIONS(middleware)

Middleware

There are some pre-defined middlewares within the middleware folder; NOTE: that the middleware inside will comply with the following rule(s):

  • Are completely reusable by the community without modification

Other middleware will be listed under the _examples/middleware/... folder for a quick copy/paste modify. As an example a LoddingAndRecovery middleware is very application dependent and therefore will be listed under the _examples/middleware/...

Benchmarks

Run on i5-7600 16 GB DDR4-2400 using Go version go1.12.5 darwin/amd64

NOTICE: pure uses a custom version of httprouter's radix tree, benchmarks can be found here the slowdown is with the use of the context package, as you can see when no SEO params are defined, and therefore no need to store anything in the context, it is faster than even lars.

go test -bench=. -benchmem=true ./...
#GithubAPI Routes: 203
   Pure: 37096 Bytes

#GPlusAPI Routes: 13
   Pure: 2792 Bytes

#ParseAPI Routes: 26
   Pure: 5040 Bytes

#Static Routes: 157
   HttpServeMux: 14992 Bytes
   Pure: 21096 Bytes


goos: darwin
goarch: arm64
BenchmarkPure_Param             11965519               100.4 ns/op           256 B/op          1 allocs/op
BenchmarkPure_Param5             8756385               138.6 ns/op           256 B/op          1 allocs/op
BenchmarkPure_Param20            4335284               276.5 ns/op           256 B/op          1 allocs/op
BenchmarkPure_ParamWrite         9980685               120.0 ns/op           256 B/op          1 allocs/op
BenchmarkPure_GithubStatic      47743062                24.77 ns/op            0 B/op          0 allocs/op
BenchmarkPure_GithubParam        8514968               139.8 ns/op           256 B/op          1 allocs/op
BenchmarkPure_GithubAll            42250             28333 ns/op           42753 B/op        167 allocs/op
BenchmarkPure_GPlusStatic       87363000                13.39 ns/op            0 B/op          0 allocs/op
BenchmarkPure_GPlusParam        10398274               113.0 ns/op           256 B/op          1 allocs/op
BenchmarkPure_GPlus2Params       9235220               128.7 ns/op           256 B/op          1 allocs/op
BenchmarkPure_GPlusAll            792037              1526 ns/op            2816 B/op         11 allocs/op
BenchmarkPure_ParseStatic       79194198                14.96 ns/op            0 B/op          0 allocs/op
BenchmarkPure_ParseParam        11391336               104.5 ns/op           256 B/op          1 allocs/op
BenchmarkPure_Parse2Params      10103078               116.2 ns/op           256 B/op          1 allocs/op
BenchmarkPure_ParseAll            498306              2417 ns/op            4096 B/op         16 allocs/op
BenchmarkPure_StaticAll           219930              5225 ns/op               0 B/op          0 allocs/op

Licenses

  • MIT License (MIT), Copyright (c) 2016 Dean Karn
  • BSD License, Copyright (c) 2013 Julien Schmidt. All rights reserved.

More Repositories

1

validator

πŸ’―Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
Go
16,425
star
2

webhooks

🎣 Webhook receiver for GitHub, Bitbucket, GitLab, Gogs
Go
949
star
3

form

πŸš‚ Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
Go
750
star
4

pool

🚀 a limited consumer goroutine or unlimited goroutine pool for easier goroutine handling and cancellation
Go
724
star
5

lars

🚨 Is a lightweight, fast and extensible zero allocation HTTP router for Go used to create customizable frameworks.
Go
386
star
6

universal-translator

πŸ’¬ i18n Translator for Go/Golang using CLDR data + pluralization rules
Go
375
star
7

log

πŸ“— Simple, configurable and scalable Structured Logging for Go.
Go
292
star
8

locales

🌎 a set of locales generated from the CLDR Project which can be used independently or within an i18n package; these were built for use with, but not exclusive to https://github.com/go-playground/universal-translator
Go
267
star
9

mold

βœ‚οΈ Is a general library to help modify or set data within data structures and other objects.
Go
225
star
10

stats

πŸ“ˆ Monitors Go MemStats + System stats such as Memory, Swap and CPU and sends via UDP anywhere you want for logging etc...
Go
170
star
11

overalls

πŸ‘–Multi-Package go project coverprofile for tools like goveralls
Go
114
star
12

statics

πŸ“ Embeds static resources into go files for single binary compilation + works with http.FileSystem + symlinks
Go
68
star
13

colors

🎨 Go color manipulation, conversion and printing library/utility
Go
67
star
14

assert

❗Basic Assertion Library used along side native go testing, with building blocks for custom assertions
Go
62
star
15

errors

πŸ’₯Error Context, Stack Trace, Types and Tags for full error handling and logging.
Go
61
star
16

kms

πŸ”ͺ Is a library that aids in graceful shutdown of a process/application
Go
47
star
17

pkg

⭐ pkg extends the core go packages with missing or additional functionality built in. All packages correspond to the std go package name with an additional suffix of `ext` to avoid naming conflicts.
Go
42
star
18

tz

Timezone Country and Zone data generated from timezonedb.com
Go
30
star
19

generate

πŸƒruns go generate recursively on a specified path or environment variable and can filter by regex
Go
30
star
20

justdoit

simple auto-compile daemon that just works
Go
19
star
21

spoon

library + program to help making zero downtime, self-upgrading programs and servers.
Go
16
star
22

retry

πŸ”„ Retry provides a set of standardized common components and abstracts away some code that normally is duplicated
Go
16
star
23

ansi

⬛ ansi contains a bunch of constants and possibly additional terminal related functionality in the future.
Go
14
star
24

sensitive

provides base types who's values should never be seen by the human eye, but still used for configuration.
Go
14
star
25

ksql

a JSON data expression lexer, parser, cli and library
Go
13
star
26

backoff

:bowtie: Backoff uses an exponential backoff algorithm to backoff between retries with optional auto-tuning functionality.
Go
12
star
27

cache

Contains multiple in-memory cache implementations including LRU & LFU
Go
11
star
28

assets

Asset Pipeline for Go HTML applications
Go
8
star
29

ws

πŸ™Œ ws creates a hub for WebSocket connections and abstracts away allot of the boilerplate code for managing connections using Gorilla WebSocket
Go
8
star
30

itertools

Go Iteration tools with a rusty flavour
Go
7
star
31

livereload

πŸ” is an asset live-reload library that allows easy registration of path & file change monitoring and notifications for https://github.com/livereload/livereload-js
JavaScript
6
star
32

relay-client-go

This package is a Go client for the Relay Job Runner https://github.com/rust-playground/relay-rs
Go
5
star
33

backoff-sys

Bare building blocks for backing off and can be used to build more complex backoff packages
Go
4
star
34

mongostore

πŸ”‘ Gorilla's session store implementation using MongoDB
Go
4
star
35

bundler

Generic Bundler to concatenate any type of files using a custom left and right delimiter, i.e. css or js files
Go
4
star
36

wave

〰️ Package wave is a thin helper layer on top of Go's net/rpc
Go
1
star