All Projects → go-playground → Pure

go-playground / Pure

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

Programming Languages

go
31211 projects - #10 most used programming language

Labels

Projects that are alternatives of or similar to Pure

Slacker
Slack Bot Framework
Stars: ✭ 495 (+338.05%)
Mutual labels:  context
Filter
ConTeXt module to process contents of a start-stop environment through an external program
Stars: ✭ 36 (-68.14%)
Mutual labels:  context
Chi
lightweight, idiomatic and composable router for building Go HTTP services
Stars: ✭ 10,581 (+9263.72%)
Mutual labels:  context
Create React Context
Polyfill for the proposed React context API
Stars: ✭ 689 (+509.73%)
Mutual labels:  context
Scs
HTTP Session Management for Go
Stars: ✭ 847 (+649.56%)
Mutual labels:  context
Parse Comments
Parse JavaScript code comments. Works with block and line comments, and should work with CSS, LESS, SASS, or any language with the same comment formats.
Stars: ✭ 53 (-53.1%)
Mutual labels:  context
Jstarcraft Rns
专注于解决推荐领域与搜索领域的两个核心问题:排序预测(Ranking)和评分预测(Rating). 为相关领域的研发人员提供完整的通用设计与参考实现. 涵盖了70多种排序预测与评分预测算法,是最快最全的Java推荐与搜索引擎.
Stars: ✭ 324 (+186.73%)
Mutual labels:  context
2018 Zjuai Pyramidboxdetector
2018 云从人头技术冠军分享方案
Stars: ✭ 100 (-11.5%)
Mutual labels:  context
Use Global Context
A new way to use “useContext” better
Stars: ✭ 34 (-69.91%)
Mutual labels:  context
Go Httpwares
Go HTTP Server Middleware and Client Tripperware
Stars: ✭ 60 (-46.9%)
Mutual labels:  context
Web3 React
🧰 A simple, maximally extensible, dependency minimized framework for building modern Ethereum dApps
Stars: ✭ 788 (+597.35%)
Mutual labels:  context
Parse Code Context
Parse code context in a single line of javascript, for functions, variable declarations, methods, prototype properties, prototype methods etc.
Stars: ✭ 7 (-93.81%)
Mutual labels:  context
Alveron
Elm & Reason inspired state management for React
Stars: ✭ 57 (-49.56%)
Mutual labels:  context
Chat
基于自然语言理解与机器学习的聊天机器人,支持多用户并发及自定义多轮对话
Stars: ✭ 516 (+356.64%)
Mutual labels:  context
React Waterfall
React store built on top of the new context API
Stars: ✭ 1,318 (+1066.37%)
Mutual labels:  context
Transmittable Thread Local
📌 TransmittableThreadLocal (TTL), the missing Java™ std lib(simple & 0-dependency) for framework/middleware, provide an enhanced InheritableThreadLocal that transmits values between threads even using thread pooling components.
Stars: ✭ 4,678 (+4039.82%)
Mutual labels:  context
Log4j2 Ttl Thread Context Map
🌳 Log4j2 TTL ThreadContextMap, Log4j2 extension integrated TransmittableThreadLocal to MDC
Stars: ✭ 41 (-63.72%)
Mutual labels:  context
Formcat
A simple and easy way to control forms in React using the React Context API
Stars: ✭ 106 (-6.19%)
Mutual labels:  context
Carskit
Java-Based Context-aware Recommendation Library
Stars: ✭ 98 (-13.27%)
Mutual labels:  context
Yewdux
Redux-like state containers for Yew apps
Stars: ✭ 58 (-48.67%)
Mutual labels:  context

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

  • [x] It sticks to Go's native implementations while providing helper functions for convenience
  • [x] 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


BenchmarkPure_Param             10000000               184 ns/op             384 B/op          2 allocs/op
BenchmarkPure_Param5            10000000               236 ns/op             384 B/op          2 allocs/op
BenchmarkPure_Param20            5000000               393 ns/op             384 B/op          2 allocs/op
BenchmarkPure_ParamWrite         5000000               240 ns/op             384 B/op          2 allocs/op
BenchmarkPure_GithubStatic      50000000                36.2 ns/op             0 B/op          0 allocs/op
BenchmarkPureGithubParam        10000000               230 ns/op             384 B/op          2 allocs/op
BenchmarkPure_GithubAll            30000             43887 ns/op           64130 B/op        334 allocs/op
BenchmarkPure_GPlusStatic       50000000                22.8 ns/op             0 B/op          0 allocs/op
BenchmarkPure_GPlusParam        10000000               192 ns/op             384 B/op          2 allocs/op
BenchmarkPure_GPlus2Params      10000000               211 ns/op             384 B/op          2 allocs/op
BenchmarkPure_GPlusAll            500000              2457 ns/op            4224 B/op         22 allocs/op
BenchmarkPure_ParseStatic       100000000               23.7 ns/op             0 B/op          0 allocs/op
BenchmarkPure_ParseParam        10000000               177 ns/op             384 B/op          2 allocs/op
BenchmarkPure_Parse2Params      10000000               193 ns/op             384 B/op          2 allocs/op
BenchmarkPure_ParseAll            500000              3751 ns/op            6144 B/op         32 allocs/op
BenchmarkPure_StaticAll           200000              8574 ns/op               0 B/op          0 allocs/op

Package Versioning

I'm jumping on the vendoring bandwagon, you should vendor this package as I will not be creating different version with gopkg.in like allot of my other libraries.

Why? because my time is spread pretty thin maintaining all of the libraries I have + LIFE, it is so freeing not to worry about it and will help me keep pouring out bigger and better things for you the community.

I am open versioning with gopkg.in should anyone request it, but this should be stable going forward.

Licenses

  • MIT License (MIT), Copyright (c) 2016 Dean Karn
  • BSD License, Copyright (c) 2013 Julien Schmidt. All rights reserved.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].