All Projects → bnkamalesh → Webgo

bnkamalesh / Webgo

Licence: mit
A minimal framework to build web apps; with handler chaining, middleware support; and most of all standard library compliant HTTP handlers(i.e. http.HandlerFunc).

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Webgo

Clevergo
👅 CleverGo is a lightweight, feature rich and high performance HTTP router for Go.
Stars: ✭ 246 (+49.09%)
Mutual labels:  middleware, web-framework, router
Twig
Twig - less is more's web server for golang
Stars: ✭ 98 (-40.61%)
Mutual labels:  middleware, webframework, router
Golf
⛳️ The Golf web framework
Stars: ✭ 248 (+50.3%)
Mutual labels:  middleware, webframework, router
Dotweb
Simple and easy go web micro framework
Stars: ✭ 1,354 (+720.61%)
Mutual labels:  middleware, webframework, router
Iris
The fastest HTTP/2 Go Web Framework. AWS Lambda, gRPC, MVC, Unique Router, Websockets, Sessions, Test suite, Dependency Injection and more. A true successor of expressjs and laravel | 谢谢 https://github.com/kataras/iris/issues/1329 |
Stars: ✭ 21,587 (+12983.03%)
Mutual labels:  middleware, web-framework, router
Min
A minimalistic web framework with route grouping and middleware chaining
Stars: ✭ 95 (-42.42%)
Mutual labels:  middleware, router
Cottage
Simple, fast HTTP router on koa.js.
Stars: ✭ 103 (-37.58%)
Mutual labels:  web-framework, router
Gin
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
Stars: ✭ 53,971 (+32609.7%)
Mutual labels:  middleware, router
Giraffe
Giraffe is an F# micro web framework for building rich web applications. It has been heavily inspired and is similar to Suave, but has been specifically designed with ASP.NET Core in mind and can be plugged into the ASP.NET Core pipeline via middleware. Giraffe applications are composed of so called HttpHandler functions which can be thought of a mixture of Suave's WebParts and ASP.NET Core's middleware.
Stars: ✭ 1,703 (+932.12%)
Mutual labels:  middleware, web-framework
Go Tgbot
Golang telegram bot API wrapper, session-based router and middleware
Stars: ✭ 90 (-45.45%)
Mutual labels:  middleware, router
Faygo
Faygo is a fast and concise Go Web framework that can be used to develop high-performance web app(especially API) with fewer codes. Just define a struct handler, faygo will automatically bind/verify the request parameters and generate the online API doc.
Stars: ✭ 1,557 (+843.64%)
Mutual labels:  middleware, web-framework
Http Router
🎉 Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)
Stars: ✭ 124 (-24.85%)
Mutual labels:  middleware, router
Jooby
The modular web framework for Java and Kotlin
Stars: ✭ 1,309 (+693.33%)
Mutual labels:  web-framework, webframework
Chi
lightweight, idiomatic and composable router for building Go HTTP services
Stars: ✭ 10,581 (+6312.73%)
Mutual labels:  middleware, router
Gemini
Model Driven REST framework to automatically generate CRUD APIs
Stars: ✭ 138 (-16.36%)
Mutual labels:  api-server, api-rest
Rapidoid
Rapidoid - Extremely Fast, Simple and Powerful Java Web Framework and HTTP Server!
Stars: ✭ 1,571 (+852.12%)
Mutual labels:  web-framework, webframework
Grip
The microframework for writing powerful web applications.
Stars: ✭ 137 (-16.97%)
Mutual labels:  web-framework, router
Foxify
The fast, easy to use & typescript ready web framework for Node.js
Stars: ✭ 138 (-16.36%)
Mutual labels:  middleware, router
Silicon
A high performance, middleware oriented C++14 http web framework please use matt-42/lithium instead
Stars: ✭ 1,721 (+943.03%)
Mutual labels:  middleware, webframework
Koatty
Koa2 + Typescript = Koatty. Use Typescript's decorator implement IOC and AOP.
Stars: ✭ 67 (-59.39%)
Mutual labels:  middleware, router

webgo gopher

coverage

WebGo v5.0.0

WebGo is a minimalistic framework for Go to build web applications (server side) with zero 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as http.HandlerFunc.

Index

  1. Router
  2. Handler chaining
  3. Middleware
  4. Helper functions
  5. HTTPS ready
  6. Graceful shutdown
  7. Logging
  8. Usage

Router

Router routes multiple paths/URIs to its respective HTTP handler. It supports defining URIs with the following patterns

  1. /api/users
    • Static URI pattern with no variables
  2. /api/users/:userID
    • URI pattern with named variable userID (named URI parameter)
    • This will not match /api/users/johndoe/account. It only matches till /api/users/johndoe/
      • If TrailingSlash is set to true, refer to sample
  3. /api/users/:misc*
    • Named URI variable misc
    • This matches everything after /api/users. e.g. /api/users/a/b/c/d

If multiple patterns match the same URI, the first matching handler would be executed. Refer to the sample to see how routes are configured. A WebGo Route is defined as following:

webgo.Route{
	// A name for the API (preferrably unique)
	Name string
	// HTTP verb, i.e. GET, POST, PUT, PATCH, HEAD, DELETE
	Method string
	// The URI pattern
	Pattern string
	// If the URI ends with a '/', should it be considered valid or not? e.g. '/api/users' vs '/api/users/'
	TrailingSlash bool
	// In case of chained handlers, should the execution continue after one of the handlers have 
	// responded to the HTTP request
	FallThroughPostResponse bool
	// The list of HTTP handlers
	Handlers []http.HandlerFunc
}

You can access named parameters of the URI using the Context function. Note: webgo Context is not available inside special handlers, since it serves no purpose

func helloWorld(w http.ResponseWriter, r *http.Request) {
	// WebGo context
	wctx := webgo.Context(r)
	// URI paramaters, map[string]string
	params := wctx.Params()
	// route, the webgo.Route which is executing this request
	route := wctx.Route
	webgo.R200(
		w,
		fmt.Sprintf(
			"Route name: '%s', params: '%s'", 
			route.Name,
			params, 
			),
	)
}

Handler chaining

Handler chaining lets you execute multiple handlers for a given route. Execution of a chain can be configured to run even after a handler has written a response to the HTTP request. This is made possible by setting FallThroughPostResponse to true (refer sample).

webgo.Route{
	Name: "chained",
	Method: http.MethodGet,
	Pattern: "/api",
	TrailingSlash: false,
	FallThroughPostResponse: true,
	Handlers []http.HandlerFunc{
		handler1,
		handler2,
		.
		.
		.
	}
}

Middleware

WebGo middlware lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method Use && UseOnSpecialHandlers to add a Middleware to the router. Following code shows how a middleware can be used.

NotFound && NotImplemented are the handlers which are considered Special handlers. webgo.Context(r) within special handlers will return nil.

import (
	"github.com/bnkamalesh/webgo/v4"
	"github.com/bnkamalesh/webgo/v4/middleware"
)

func routes() []*webgo.Route {
	return []*webgo.Route{
		&webo.Route{
			Name: "home",
			Method: http.http.MethodGet,
			Pattern: "/",
			Handlers: []http.HandlerFunc{
				func(w http.ResponseWriter, r *http.Request) {
					webgo.R200(w, "home")
				}
			},
		},
	}
}

func main() {
	router := webgo.NewRouter(*webgo.Config{
		Host:         "",
		Port:         "8080",
		ReadTimeout:  15 * time.Second,
		WriteTimeout: 60 * time.Second,
	}, routes())

	router.UseOnSpecialHandlers(middleware.AccessLog)
	
	router.Use(middleware.AccessLog)

	router.Start()
}

Any number of middleware can be added to the router, the order of execution of middleware would be LIFO (Last In First Out). i.e. in case of the following code

func main() {
	router.Use(middleware.AccessLog)
	router.Use(middleware.CorsWrap())
}

CorsWrap would be executed first, followed by AccessLog.

Helper functions

WebGo provides a few helper functions.

  1. ResponseStatus(w http.ResponseWriter) get the HTTP status code from response writer
  2. SendHeader(w http.ResponseWriter, rCode int) - Send only an HTTP response header with the provided response code.
  3. Send(w http.ResponseWriter, contentType string, data interface{}, rCode int) - Send any response as is, with the provided content type and response code
  4. SendResponse(w http.ResponseWriter, data interface{}, rCode int) - Send a JSON response wrapped in WebGo's default response struct.
  5. SendError(w http.ResponseWriter, data interface{}, rCode int) - Send a JSON response wrapped in WebGo's default error response struct
  6. Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template) - Render renders a Go template, with the provided data & response code.

You can find other helper functions here.

When using Send or SendResponse, the response is wrapped in WebGo's response struct and is serialized as JSON.

{
	"data": "<any valid JSON payload>",
	"status": "<HTTP status code, of type integer>"
}

When using SendError, the response is wrapped in WebGo's error response struct and is serialzied as JSON.

{
	"errors": "<any valid JSON payload>",
	"status": "<HTTP status code, of type integer>"
}

HTTPS ready

HTTPS server can be started easily, by providing the key & cert file. You can also have both HTTP & HTTPS servers running side by side.

Start HTTPS server

cfg := &webgo.Config{
	Port: "80",
	HTTPSPort: "443",
	CertFile: "/path/to/certfile",
	KeyFile: "/path/to/keyfile",
}
router := webgo.NewRouter(cfg, routes())
router.StartHTTPS()

Starting both HTTP & HTTPS server

cfg := &webgo.Config{
	Port: "80",
	HTTPSPort: "443",
	CertFile: "/path/to/certfile",
	KeyFile: "/path/to/keyfile",
}

router := webgo.NewRouter(cfg, routes())
go router.StartHTTPS()
router.Start()

Graceful shutdown

Graceful shutdown lets you shutdown the server without affecting any live connections/clients connected to the server. It will complete executing all the active/live requests before shutting down.

Sample code to show how to use shutdown

func main() {
	osSig := make(chan os.Signal, 5)

	cfg := &webgo.Config{
		Host:            "",
		Port:            "8080",
		ReadTimeout:     15 * time.Second,
		WriteTimeout:    60 * time.Second,
		ShutdownTimeout: 15 * time.Second,
	}
	router := webgo.NewRouter(cfg, routes())

	go func() {
		<-osSig
		// Initiate HTTP server shutdown
		err := router.Shutdown()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		} else {
			fmt.Println("shutdown complete")
			os.Exit(0)
		}

		// If you have HTTPS server running, you can use the following code
		// err := router.ShutdownHTTPS()
		// if err != nil {
		// 	fmt.Println(err)
		// 	os.Exit(1)
		// } else {
		// 	fmt.Println("shutdown complete")
		// 	os.Exit(0)
		// }
	}()

	signal.Notify(osSig, os.Interrupt, syscall.SIGTERM)

	router.Start()

	for {
		// Prevent main thread from exiting, and wait for shutdown to complete
		time.Sleep(time.Second * 1)
	}
}

Logging

WebGo exposes a singleton & global scoped logger variable LOGHANDLER with which you can plug in your custom logger by implementing the Logger interface.

type Logger interface {
    Debug(data ...interface{})
    Info(data ...interface{})
    Warn(data ...interface{})
    Error(data ...interface{})
    Fatal(data ...interface{})
}

Configuring the default Logger

The default logger uses Go standard library's log.Logger with os.Stdout (for debug and info logs) & os.Stderr (for warning, error, fatal) as default io.Writers. You can set the io.Writer as well as disable specific types of logs using the GlobalLoggerConfig(stdout, stderr, cfgs...) function.

GlobalLoggerConfig(nil, nil, LogCfgDisableDebug, LogCfgDisableInfo...)

Usage is shown in cmd/main.go.

Usage

A fully functional sample is provided here. You can try the following API calls with the sample app.

  1. http://localhost:8080/
    • Route with no named parameters configured
  2. http://localhost:8080/matchall/
  3. `http://localhost:8080/api/

How to run the sample

If you have Go installed on your computer, open the terminal and:

$ cd $GOPATH/src
$ mkdir -p github.com/bnkamalesh
$ cd github.com/bnkamalesh
$ git clone https://github.com/bnkamalesh/webgo.git
$ cd webgo
$ go run cmd/main.go

Info 2020/06/03 12:55:26 HTTP server, listening on :8080

Or if you have Docker, open the terminal and:

$ git clone https://github.com/bnkamalesh/webgo.git
$ cd webgo
$ docker run \
-p 8080:8080 \
-v ${PWD}:/go/src/github.com/bnkamalesh/webgo/ \
-w /go/src/github.com/bnkamalesh/webgo/cmd \
--rm -ti golang:latest go run main.go

Info 2020/06/03 12:55:26 HTTP server, listening on :8080

Benchmark

You can view benchmark results at the following repos:

  1. the-benchmarker
  2. go-web-framework-benchmark

Contributing

Refer here to find out details about making a contribution

Credits

Thanks to all the contributors

The gopher

The gopher used here was created using Gopherize.me. WebGo stays out of developers' way, so sitback and enjoy a cup of coffee like this gopher.

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].