Gearbox :gear: is a web framework written in Go with a focus on high performance


DeepSource

gearbox ⚙️ is a web framework for building micro services written in Go with a focus on high performance. It's built on fasthttp which is up to 10x faster than net/http

gearbox seeks to be

  • Secure 🔐
  • Fast 🚀
  • Easy to use 👓
  • Lightweight

Supported Go versions & installation

⚙️ gearbox requires version 1.14 or higher of Go (Download Go)

Just use go get to download and install gearbox

go get -u github.com/gogearbox/gearbox

Examples

package main

import (
	"github.com/gogearbox/gearbox"
)

func main() {
	// Setup gearbox
	gb := gearbox.New()

	// Define your handlers
	gb.Get("/hello", func(ctx gearbox.Context) {
		ctx.SendString("Hello World!")
	})

	// Start service
	gb.Start(":3000")
}

Parameters

package main

import (
	"github.com/gogearbox/gearbox"
)

func main() {
	// Setup gearbox
	gb := gearbox.New()

	// Handler with parameter
	gb.Get("/users/:user", func(ctx gearbox.Context) {
		ctx.SendString(ctx.Param("user"))
	})

	// Start service
	gb.Start(":3000")
}

Middlewares

package main

import (
	"log"

	"github.com/gogearbox/gearbox"
)

func main() {
	// Setup gearbox
	gb := gearbox.New()

	// create a logger middleware
	logMiddleware := func(ctx gearbox.Context) {
		log.Printf("log message!")

		// Next is what allows the request to continue to the next
		// middleware/handler
		ctx.Next()
	}

	// create an unauthorized middleware
	unAuthorizedMiddleware := func(ctx gearbox.Context) {
		ctx.Status(gearbox.StatusUnauthorized)
			.SendString("You are unauthorized to access this page!")
	}

	// Register the log middleware for all requests
	gb.Use(logMiddleware)

	// Define your handlers
	gb.Get("/hello", func(ctx gearbox.Context) {
		ctx.SendString("Hello World!")
	})

	// Register the routes to be used when grouping routes
	routes := []*gearbox.Route{
		gb.Get("/id", func(ctx gearbox.Context) {
			ctx.SendString("User X")
		}),
		gb.Delete("/id", func(ctx gearbox.Context) {
			ctx.SendString("Deleted")
		}),
	}

	// Group account routes
	accountRoutes := gb.Group("/account", routes)

	// Group account routes to be under api
	gb.Group("/api", accountRoutes)

	// Define a route with unAuthorizedMiddleware as the middleware
	// you can define as many middlewares as you want and have
	// the handler as the last argument
	gb.Get("/protected", unAuthorizedMiddleware, func(ctx gearbox.Context) {
		ctx.SendString("You accessed a protected page")
	})

	// Start service
	gb.Start(":3000")
}

Static Files

package main

import (
	"github.com/gogearbox/gearbox"
)

func main() {
	// Setup gearbox
	gb := gearbox.New()

	// Serve files in assets directory for prefix static
	// for example /static/gearbox.png, etc.
	gb.Static("/static", "./assets")

	// Start service
	gb.Start(":3000")
}

Benchmarks

  • CPU 3.1 GHz Intel Xeon® Platinum 8175M (24 physical cores, 48 logical cores)
  • MEMORY 192GB
  • GO go 1.14.6 linux/amd64
  • OS Linux

For more results, check Our Docs

Contribute & Support

Check Our Docs for more information about gearbox and how to contribute

Sponsors

Organizations that are helping to manage, promote, and support Gearbox ⚙️

trella: A B2B technology platform and trucking
marketplace that connects shippers with carriers

Who uses Gearbox

Gearbox ⚙️ is being used by multiple organizations including but not limited to

Contributors

Get in touch!

Feel free to chat with us on Discord, or email us at [email protected] if you have questions, or suggestions

License

gearbox is licensed under MIT License

Logo is created by Mahmoud Sayed and distributed under Creative Commons License

Third-party library licenses

Owner
Gearbox
:gear: gearbox is a web framework written in Go with a focus on high performance
Gearbox
Comments
  • my ubuntu i686 system get the wrong result

    my ubuntu i686 system get the wrong result

    Describe the bug

    package main
    
    import (
    	"log"
    
    	"github.com/gogearbox/gearbox"
    )
    
    func main() {
    	gb := gearbox.New()
    	logMiddleware := func(ctx gearbox.Context) {
    		log.Printf("log message!")
    		ctx.Next()
    	}
    	gb.Use(logMiddleware)
    	routes := []*gearbox.Route{
    		gb.Get("/id", func(ctx gearbox.Context) {
    			ctx.SendString("User X")
    		}),
    		gb.Delete("/del", func(ctx gearbox.Context) {
    			ctx.SendString("Deleted")
    		}),
    	}
    
    	accountRoutes := gb.Group("/account", routes)
    	gb.Group("/api", accountRoutes)
    	gb.Start(":3000")
    }
    

    go run main.go curl http://localhost:3000/api/account/id output: Deleted To Reproduce Steps to reproduce the behavior:

    Expected behavior A clear and concise description of what you expected to happen.

    Actual behavior curl http://localhost:3000/api/account/id

    My x86 system result "Deleted" but my amd64 system result "User X" , it's so strange

    Version/Commit gear1.1.1 , go1.15.7

  • Set custom error handlers

    Set custom error handlers

    Is your feature request related to a problem? Please describe. It would be great to customize the error handlers that are used for the various potential errors. For example a simple HTML 500-error or some additional logic.

    Describe the solution you'd like Something akin to NotFound() like NotAllowed(), InternalServerError(), IAmATeapot()

  • Is a Ternary Search Tree really better?

    Is a Ternary Search Tree really better?

    I'm curious about the choice for a Ternary Search Tree instead of just a normal map. I wrote a quick benchmark an no matter how I configure it the map always uses 90% less memory and is 10% to 500% faster depending on the hit rate. Do you have some benchmark to show why it is better for your case?

    package main
    
    import (
    	"container/list"
    	"math/rand"
    	"runtime"
    	"testing"
    )
    
    // Basic Implementation for Ternary Search Tree (TST)
    
    // tst returns Ternary Search Tree
    type tst interface {
    	Set(word []byte, value interface{})
    	Get(word []byte) interface{}
    	GetString(word string) interface{}
    }
    
    // Ternary Search Tree node that holds a single character and value if there is
    type tstNode struct {
    	lower  *tstNode
    	higher *tstNode
    	equal  *tstNode
    	char   byte
    	value  interface{}
    }
    
    // newTST returns Ternary Search Tree
    func newTST() tst {
    	return &tstNode{}
    }
    
    // Set adds a value to provided key
    func (t *tstNode) Set(key []byte, value interface{}) {
    	if len(key) < 1 {
    		return
    	}
    
    	t.insert(t, key, 0, value)
    }
    
    // Get gets the value of provided key if it's existing, otherwise returns nil
    func (t *tstNode) Get(key []byte) interface{} {
    	length := len(key)
    	if length < 1 || t == nil {
    		return nil
    	}
    	lastElm := length - 1
    
    	n := t
    	idx := 0
    	char := key[idx]
    	for n != nil {
    		if char < n.char {
    			n = n.lower
    		} else if char > n.char {
    			n = n.higher
    		} else {
    			if idx == lastElm {
    				return n.value
    			}
    
    			idx++
    			n = n.equal
    			char = key[idx]
    		}
    	}
    	return nil
    }
    
    // Get gets the value of provided key (string) if it's existing, otherwise returns nil
    func (t *tstNode) GetString(key string) interface{} {
    	return t.Get([]byte(key))
    }
    
    // insert is an internal method for inserting a []byte with value in TST
    func (t *tstNode) insert(n *tstNode, key []byte, index int, value interface{}) *tstNode {
    	char := key[index]
    	lastElm := len(key) - 1
    
    	if n == nil {
    		n = &tstNode{char: char}
    	}
    
    	if char < n.char {
    		n.lower = t.insert(n.lower, key, index, value)
    	} else if char > n.char {
    		n.higher = t.insert(n.higher, key, index, value)
    	} else {
    		if index == lastElm {
    			n.value = value
    		} else {
    			n.equal = t.insert(n.equal, key, index+1, value)
    		}
    	}
    
    	return n
    }
    
    // RandBytes generates random string from English letters
    func RandBytes() []byte {
    	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    	b := make([]byte, rand.Intn(100))
    	for i := range b {
    		b[i] = letterBytes[rand.Intn(len(letterBytes))]
    	}
    	return b
    }
    
    var (
    	keys = make([][]byte, 1000)
    	T    tst
    	M    = make(map[string]interface{})
    
    	Sink interface{}
    )
    
    func init() {
    	T = newTST()
    	rand.Seed(0)
    
    	for i := 0; i < len(keys); i++ {
    		keys[i] = RandBytes()
    	}
    
    	rand.Seed(0)
    	var b, a runtime.MemStats
    	runtime.ReadMemStats(&b)
    	for i := 0; i < 500; i++ { // Only fill half of the keys so we get a 50% hit rate.
    		T.Set(keys[i], &list.Element{})
    	}
    	runtime.ReadMemStats(&a)
    	println(a.Alloc - b.Alloc)
    
    	rand.Seed(0)
    	runtime.ReadMemStats(&b)
    	for i := 0; i < 500; i++ { // Only fill half of the keys so we get a 50% hit rate.
    		M[string(keys[i])] = &list.Element{}
    	}
    	runtime.ReadMemStats(&a)
    	println(a.Alloc - b.Alloc)
    }
    
    func BenchmarkTST(b *testing.B) {
    	for n := 0; n < b.N; n++ {
    		Sink = T.Get(keys[(n*31)%len(keys)]) // Lookup a semi random key (using rand.Intn is too heavy here compared to the operation we are benchmarking).
    	}
    }
    
    func BenchmarkMap(b *testing.B) {
    	for n := 0; n < b.N; n++ {
    		Sink = M[string(keys[(n*31)%len(keys)])] // Lookup a semi random key (using rand.Intn is too heavy here compared to the operation we are benchmarking).
    	}
    }
    
  • [Proposal] Contribute to a benchmark

    [Proposal] Contribute to a benchmark

    Hi,

    I'm leading a benchmarking project => https://github.com/the-benchmarker/web-frameworks

    The purpose of this project is to compare performances (other indicators will come), based on a fairest, as we can, comparison for go frameworks (comparing on the same version, production-grade environments, same compilation options ...).

    Do you mind that I (or any member) add gearbox ? :heart:

    Regards,

  • Use []bytes instead of strings in router

    Use []bytes instead of strings in router

    Fixes #11

    Changes proposed in this pull request:

    • Use []bytes instead of strings in router
    • Improve route matching
    • Updating tests according to changes
  • Support parameters in paths

    Support parameters in paths

    Allow user to specify parameters in paths while adding routes (e.g. gearbox.Get("/user/:name, ...)).

    Discussions / suggestions is open here

    • The proper delimiter (:name, or {name})
    • How these parameters will be passed to handler
  • Prometheus middleware

    Prometheus middleware

    I'd love to use the project because of it's awesome performance but we need Prometheus metrics for our production env so is it possible for you to write Prometheus middlewares for it?

  •  runtime error: slice bounds out of range [1:0]

    runtime error: slice bounds out of range [1:0]

    I initialize routes like this:

    func (h *HttpSrv) createRoutes() {
    	h.g.Get("/dsp/cpc/:sspId", h.handleGetBids)
    	h.g.Post("/dsp/cpc/:sspId", h.handlePostBids)
    
    	h.g.Get("/dsp-native/cpc/:sspId", h.handleNativeGetBids)
    	h.g.Post("/dsp-native/cpc/:sspId", h.handleNativePostBids)
    
    	h.g.Get("/dsp-popunder/cpc/:sspId", h.handlePopunderGetBids)
    	h.g.Post("/dsp-popunder/cpc/:sspId", h.handlePopunderPostBids)
    }
    
    func (h *HttpSrv) handleGetBids(ctx gearbox.Context) {
    	mw, ok := sspinfo.GetSspProcessorsPool().GetPushProcessor(ctx.Param("sspId"))
    	if ok {
    		mw.ExecQueryParamsHandler(ctx)
    	} else {
    		ctx.Status(gearbox.StatusNotFound)
    	}
    }
    

    And catching the next panic:

    panic: runtime error: slice bounds out of range [1:0]
    goroutine 2027 [running]:
    github.com/gogearbox/gearbox.(*node).matchRoute(0xc000557c00, 0xc031aa2900, 0x0, 0xc030b9b320, 0xc02e463f68, 0xc032ece400, 0x3)
    	/go/pkg/mod/github.com/gogearbox/[email protected]/tree.go:134 +0x289
    github.com/gogearbox/gearbox.(*router).Handler(0xc0005d0c80, 0xc0323d7400)
    	/go/pkg/mod/github.com/gogearbox/[email protected]/router.go:163 +0x745
    github.com/valyala/fasthttp.(*Server).serveConn(0xc02e54c000, 0xa69b38, 0xc031106420, 0x0, 0x0)
    	/go/pkg/mod/github.com/valyala/[email protected]/server.go:2193 +0x128e
    github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc02e468640, 0xc032c9b0a0)
    	/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:223 +0xba
    github.com/valyala/fasthttp.(*workerPool).getCh.func1(0xc02e468640, 0xc032c9b0a0, 0x905520, 0xc032c9b0a0)
    	/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x35
    created by github.com/valyala/fasthttp.(*workerPool).getCh
    	/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:194 +0x11f
    

    What the reason could be?

  • Pass data from middleware to handler

    Pass data from middleware to handler

    Is your feature request related to a problem? Please describe. I have a middleware that checks and parse the JWT. I would like to pass from that middleware to the handler the parsed JWT so I don't need to parse it again. I saw that the fiber has this feature but I didn't saw anything related here.

    Describe the solution you'd like Be able to set in context some data that will be available in the next middleware or handler

  • wrap standard net/http handler

    wrap standard net/http handler

    First of all I am not sure maybe there is an work around for that but i cant find it.

    Here is the use case: I like to use opencensus.io for request tracking and prometheus for metrics export. If you are using standard net/http you can do that like this

    
    import "contrib.go.opencensus.io/exporter/prometheus"
    
    // Then create the actual exporter
    pe, err := prometheus.NewExporter(prometheus.Options{
        Namespace: "demo",
    })
    

    pe is http.handler

    Probably if you are using standalone fasthttp you can use fasthttpadaptor to wrap the net/http handler. Are there an option to attach fasthttp.RequestHandler directly to the gearbox ?

  • Introduce an implementation for workers in Gearbox

    Introduce an implementation for workers in Gearbox

    I think we need to implement something like Active Job on Rails for job scheduling

    • We need to write some test for the worker's implementation
    • We need to implement an adaptor for the FastHttp worker-pool
  • broken link to your docs

    broken link to your docs

    Describe the bug Just above this part of your homepage the link to your documentation point to an unsafe location:

    To Reproduce Just click the provided link

    Expected behavior Your doc

    Actual behavior Some redirections to something not related to gearbox

  • Bump github.com/valyala/fasthttp from 1.40.0 to 1.43.0

    Bump github.com/valyala/fasthttp from 1.40.0 to 1.43.0

    Bumps github.com/valyala/fasthttp from 1.40.0 to 1.43.0.

    Release notes

    Sourced from github.com/valyala/fasthttp's releases.

    v1.43.0

    • dbf457e Revert "feat: support mulit/range (#1398)" (#1446) (Erik Dubbelboer)
    • c50de95 client.go fix addMissingPort() (#1444) (Sergey Ponomarev)

    v1.42.0

    • 4995135 feat: add ShutdownWithContext (#1383) (kinggo)
    • 7b3bf58 style: modify typo and remove repeated type conversions (#1437) (kinggo)
    • 8f43443 Wait for the response of pipelineWork in background and return it to pool (#1436) (Andy Pan)
    • c367454 Fix some potential pool leaks (#1433) (Andy Pan)
    • b32a3dd Use time.Until(deadline) instead of -time.Since(deadline) (#1434) (Andy Pan)
    • 8a60232 Assert with *net.TCPConn instead of *net.TCPListener in acceptConn() for TCP sockets (#1432) (Andy Pan)
    • c57a2ce Make sure nothing is nil in tmp slice (#1423) (hs son)
    • f095481 Request.SetTimeout (#1415) (brian-armstrong-discord)
    • c88dd5d fix form empty field error when used with pipe (#1417) (nick9822)
    • a468a7d feat: support mulit/range (#1398) (byene0923)
    • 3963a79 feat: add PeekKeys and PeekTrailerKeys (#1405) (kinggo)
    • eca86de fix: (#1410) (byene0923)
    • e214137 fix: ignore body should not set content-length of streaming (#1406) (byene0923)

    v1.41.0

    • 128e9b3 optimize: adjust the behavior of PeekAll based on VisitAll (#1403) (kinggo)
    • 2c8ce3b feat: add header.PeekAll (#1394) (kinggo)
    • d404f2d make RequestCtx's userdata accept keys that are of type: interface{} (#1387) (pj)
    • bcf7e8e test: merge test in adaptor_test.go (#1381) (kinggo)
    • 31fdc79 resolve CVE-2022-27664 (#1377) (Craig O'Donnell)
    • 40eec0b byte to string unsafe conversion in fasthttpadaptor ConvertRequest method (#1375) (Emre Savcı)
    • a696949 Deprecate Go 1.15 (#1379) (Aoang)
    Commits
    • dbf457e Revert "feat: support mulit/range (#1398)" (#1446)
    • c50de95 client.go fix addMissingPort() (#1444)
    • 4995135 feat: add ShutdownWithContext (#1383)
    • 7b3bf58 style: modify typo and remove repeated type conversions (#1437)
    • 8f43443 Wait for the response of pipelineWork in background and return it to pool (#1...
    • c367454 Fix some potential pool leaks (#1433)
    • b32a3dd Use time.Until(deadline) instead of -time.Since(deadline) (#1434)
    • 8a60232 Assert with *net.TCPConn instead of *net.TCPListener in acceptConn() for TCP ...
    • c57a2ce Make sure nothing is nil in tmp slice (#1423)
    • f095481 Request.SetTimeout (#1415)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 1, 2023
High performance, minimalist Go web framework
High performance, minimalist Go web framework

Supported Go versions As of version 4.0.0, Echo is available as a Go module. Therefore a Go version capable of understanding /vN suffixed imports is r

Jan 2, 2023
hiboot is a high performance web and cli application framework with dependency injection support

Hiboot - web/cli application framework About Hiboot is a cloud native web and cli application framework written in Go. Hiboot is not trying to reinven

Nov 20, 2022
High performance, simple Go web framework

Elton Elton的实现参考了koa以及echo,中间件的调整均为洋葱模型:请求由外至内,响应由内至外。主要特性如下: 处理函数(中间件)均以返回error的形式响应出错,方便使用统一的出错处理中间件将出错统一转换为对应的输出(JSON),并根据出错的类型等生成各类统计分析 成功响应数据直接赋值

Dec 17, 2022
beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 8, 2023
letgo is an open-source, high-performance web framework for the Go programming language.

high-performance Lightweight web framework for the Go programming language. golang web framework,高可用golang web框架,go语言 web框架 ,go web

Sep 23, 2022
Dragon 🐲 🐲 🐲 is an enterprise high performance web framework with Go for the feature and comfortable develop.

Dragon start dragon ab performance Dragon ?? ?? ?? is a lightweight high performance web framework with Go for the feature and comfortable develop. 中文

Sep 14, 2022
Dragon 🐲 🐲 🐲 is a lightweight high performance web framework with Go for the feature and comfortable develop.

Dragon project new link start dragon ab performance Dragon ?? ?? ?? is a lightweight high performance web framework with Go for the feature and comfor

Sep 6, 2022
Microservice framework following best cloud practices with a focus on productivity.

patron Patron is a framework for creating microservices, originally created by Sotiris Mantzaris (https://github.com/mantzas). This fork is maintained

Dec 22, 2022
Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance. Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。
Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance.  Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。

Tigo(For English Documentation Click Here) 一个使用Go语言开发的web框架。 相关工具及插件 tiger tiger是一个专门为Tigo框架量身定做的脚手架工具,可以使用tiger新建Tigo项目或者执行其他操作。

Jan 5, 2023
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.

GoFrame English | 简体中文 GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang. If you're a

Jan 2, 2023
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.

Flamingo Framework Flamingo is a web framework based on Go. It is designed to build pluggable and maintainable web projects. It is production ready, f

Jan 5, 2023
Golanger Web Framework is a lightweight framework for writing web applications in Go.

/* Copyright 2013 Golanger.com. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

Nov 14, 2022
The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework.

jin About The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework. If thi

Jul 14, 2022
Kubewrap - kubewrap is an kubernetes command line utility with a focus to explore the kubernetes REST API's leveraging the go libraries available along with golang and cobra packages.

Kubewrap kubewrap is an kubernetes cli wrapper with a focus to explore the kubernetes REST API's leveraging the go libraries available along with gola

Nov 20, 2022
Package macaron is a high productive and modular web framework in Go.
Package macaron is a high productive and modular web framework in Go.

Macaron Package macaron is a high productive and modular web framework in Go. Getting Started The minimum requirement of Go is 1.6. To install Macaron

Jan 2, 2023
A high productivity, full-stack web framework for the Go language.

Revel Framework A high productivity, full-stack web framework for the Go language. Current Version: 1.0.0 (2020-07-11) Supports go.mod package managem

Jan 7, 2023
Goal is a toolkit for high productivity web development in Go language in the spirit of Revel Framework that is built around the concept of code generation.

Goal Goal is a set of tools for high productivity web development in Go language. Goal, being mostly inspired by Revel Framework and its discussions,

Sep 27, 2021