Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/bnkamalesh/webgo

A microframework to build web apps; with handler chaining, middleware support, and most of all; standard library compliant HTTP handlers(i.e. http.HandlerFunc).
https://github.com/bnkamalesh/webgo

api-rest api-server awesome-go go golang golang-library golang-module golang-server microframework middleware multiplexer router server-sent-events web-framework webframework webgo

Last synced: 23 days ago
JSON representation

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

Awesome Lists containing this project

README

        

webgo gopher

[![](https://github.com/bnkamalesh/webgo/actions/workflows/tests.yaml/badge.svg)](https://github.com/bnkamalesh/webgo/actions/workflows/tests.yaml)
[![coverage](https://img.shields.io/codecov/c/github/bnkamalesh/webgo.svg)](https://codecov.io/gh/bnkamalesh/webgo)
[![](https://goreportcard.com/badge/github.com/bnkamalesh/webgo)](https://goreportcard.com/report/github.com/bnkamalesh/webgo)
[![](https://api.codeclimate.com/v1/badges/85b3a55c3fa6b4c5338d/maintainability)](https://codeclimate.com/github/bnkamalesh/webgo/maintainability)
[![](https://godoc.org/github.com/nathany/looper?status.svg)](http://godoc.org/github.com/bnkamalesh/webgo)
[![](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#web-frameworks)

# WebGo v7.0.4

WebGo is a minimalistic router for [Go](https://golang.org) to build web applications (server side) with no 3rd party dependencies. WebGo will always be Go standard library compliant; with the HTTP handlers having the same signature as [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc).

### Contents

1. [Router](https://github.com/bnkamalesh/webgo#router)
2. [Handler chaining](https://github.com/bnkamalesh/webgo#handler-chaining)
3. [Middleware](https://github.com/bnkamalesh/webgo#middleware)
4. [Error handling](https://github.com/bnkamalesh/webgo#error-handling)
5. [Helper functions](https://github.com/bnkamalesh/webgo#helper-functions)
6. [HTTPS ready](https://github.com/bnkamalesh/webgo#https-ready)
7. [Graceful shutdown](https://github.com/bnkamalesh/webgo#graceful-shutdown)
8. [Logging](https://github.com/bnkamalesh/webgo#logging)
9. [Server-Sent Events](https://github.com/bnkamalesh/webgo#server-sent-events)
10. [Usage](https://github.com/bnkamalesh/webgo#usage)

## Router

Webgo has a simplistic, linear path matching router and supports defining [URI](https://developer.mozilla.org/en-US/docs/Glossary/URI)s with the following patterns

1. `/api/users` - URI with no dynamic values
2. `/api/users/:userID`
- URI with a named parameter, `userID`
- If TrailingSlash is set to true, it will accept the URI ending with a '/', refer to [sample](https://github.com/bnkamalesh/webgo#sample)
3. `/api/users/:misc*`
- Named URI parameter `misc`, with a wildcard suffix '\*'
- This matches everything after `/api/users`. e.g. `/api/users/a/b/c/d`

When there are multiple handlers matching the same URI, only the first occurring handler will handle the request.
Refer to the [sample](https://github.com/bnkamalesh/webgo#sample) to see how routes are configured. You can access named parameters of the URI using the `Context` function.

Note: webgo Context is **not** available inside the special handlers (not found & method not implemented)

```golang
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, if you set `FallThroughPostResponse` to `true` (refer [sample](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L70)).

## Middleware

WebGo [middlware](https://godoc.org/github.com/bnkamalesh/webgo#Middleware) lets you wrap all the routes with a middleware unlike handler chaining. The router exposes a method [Use](https://godoc.org/github.com/bnkamalesh/webgo#Router.Use) && [UseOnSpecialHandlers](https://godoc.org/github.com/bnkamalesh/webgo#Router.UseOnSpecialHandlers) to add a Middleware to the router.

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

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

```golang
func main() {
router.Use(accesslog.AccessLog, cors.CORS(nil))
router.Use()
}
```

**_CorsWrap_** would be executed first, followed by **_AccessLog_**.

## Error handling

Webgo context has 2 methods to [set](https://github.com/bnkamalesh/webgo/blob/master/webgo.go#L60) & [get](https://github.com/bnkamalesh/webgo/blob/master/webgo.go#L66) erro within a request context. It enables Webgo to implement a single middleware where you can handle error returned within an HTTP handler. [set error](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L45), [get error](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go#L51).

## Helper functions

WebGo provides a few helper functions. When using `Send` or `SendResponse` (other Rxxx responder functions), the response is wrapped in WebGo's [response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L17) and is serialized as JSON.

```json
{
"data": "",
"status": ""
}
```

When using `SendError`, the response is wrapped in WebGo's [error response struct](https://github.com/bnkamalesh/webgo/blob/master/responses.go#L23) and is serialzied as JSON.

```json
{
"errors": "",
"status": ""
}
```

## 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

```golang
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

```golang
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. Any new connection request after initiating a shutdown would be ignored.

Sample code to show how to use shutdown

```golang
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)
// }
}()

go func(){
time.Sleep(time.Second*15)
signal.Notify(osSig, os.Interrupt, syscall.SIGTERM)
}()

router.Start()
}
```

## Logging

WebGo exposes a singleton & global scoped logger variable [LOGHANDLER](https://godoc.org/github.com/bnkamalesh/webgo#Logger) with which you can plug in your custom logger by implementing the [Logger](https://godoc.org/github.com/bnkamalesh/webgo#Logger) 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.

## Server-Sent Events

[MDN has a very good documentation of what SSE (Server-Sent Events)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) are. The sample app provided shows how to use the SSE extension of webgo.

## Usage

A fully functional sample is provided [here](https://github.com/bnkamalesh/webgo/blob/master/cmd/main.go).

### Benchmark

1. [the-benchmarker](https://github.com/the-benchmarker/web-frameworks)
2. [go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark)

### Contributing

Refer [here](https://github.com/bnkamalesh/webgo/blob/master/CONTRIBUTING.md) to find out details about making a contribution

### Credits

Thanks to all the [contributors](https://github.com/bnkamalesh/webgo/graphs/contributors)

## The gopher

The gopher used here was created using [Gopherize.me](https://gopherize.me/). WebGo stays out of developers' way, so sitback and enjoy a cup of coffee.