Gobis is a lightweight API Gateway written in go which can be used programmatically or as a standalone server.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
gobistest
test-integration
vendor
.gitignore
.travis.yml
LICENSE
README.md
builder.go
builder_test.go
ctx_dirty_headers.go
ctx_helper.go
ctx_helper_test.go
ctx_middlewares.go
ctx_router.go
default_handler.go
gobis_suite_test.go
handler.go
middleware.go
middleware_chain.go
proxy_route.go
proxy_route_test.go
route_transport.go
route_transport_test.go
router_factory.go
router_factory_test.go
utils.go
utils_test.go

README.md

Gobis Build Status GoDoc

Gobis is a lightweight API Gateway written in go which can be used programmatically or as a standalone server.

It's largely inspired by Netflix/zuul.

Summary

Installation

go get github/orange-cloudfoundry/gobis

Usage

Gobis provide an handler to make it useable on your server.

You can found found gobis.ProxyRoute options in the godoc: https://godoc.org/github.com/orange-cloudfoundry/gobis#ProxyRoute

Example:

package main
import (
        "github.com/orange-cloudfoundry/gobis"
        "github.com/orange-cloudfoundry/gobis-middlewares/cors"
        log "github.com/sirupsen/logrus"
        "net/http"
)
func main(){
	builder := gobis.Builder()
	routes := builder.AddRoute("/app/**", "http://www.mocky.io/v2/595625d22900008702cd71e8").
		WithName("myapi").
        WithMiddlewareParams(cors.CorsConfig{
            Cors: &cors.CorsOptions{
                AllowedOrigins: []string{"http://localhost"},
            },
        }).
        Build()
        
    log.SetLevel(log.DebugLevel) // set verbosity to debug for logs
    gobisHandler, err := gobis.NewHandler(routes, cors.NewCors()) // we add cors middleware
    if err != nil {
            panic(err)
    }
    err = http.ListenAndServe(":8080", gobisHandler)
    if err != nil {
            panic(err)
    }
}

The builder is a more convenient way to build complex and multiple route programmatically see doc Builder.

You can see doc DefaultHandlerConfig to know more about possible parameters.

You can also see doc ProxyRoute to see available options for routes.

Headers sent by gobis to reversed app

Gobis will send some headers to the app when the request is forwarded:

  • X-Gobis-Forward: This is a dummy header to say to the app that the requested was forwarded by gobis.
  • X-Gobis-Username: User name of a logged user set by a middleware.
  • X-Gobis-Groups: User's groups of a logged user set by a middleware.

Example using gobis as a middleware

package main
import (
	"github.com/orange-cloudfoundry/gobis"
	"github.com/orange-cloudfoundry/gobis-middlewares/cors"
	"github.com/gorilla/mux"
	"net/http"
)
func main() {
	rtr := mux.NewRouter()
	rtr.HandleFunc("/hello", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    		w.Write([]byte("hello world"))
    }))
	builder := gobis.Builder()
    routes := builder.AddRoute("/app/**", "http://www.mocky.io/v2/595625d22900008702cd71e8").
        WithName("myapi").
        WithMiddlewareParams(cors.CorsConfig{
            Cors: &cors.CorsOptions{
                AllowedOrigins: []string{"http://localhost"},
            },
        }).
        Build()
        
	mid, err := gobis.NewGobisMiddleware(routes)
	if err != nil {
		panic(err)
	}
	
	err = http.ListenAndServe(":8080", mid(rtr))
	if err != nil {
		panic(err)
	}

	// hitting /hello will show hello world
	// hitting /app/something will forward against gobis
}

Middlewares

Gobis permit to add middlewares on handler to be able to enhance your upstream url, for example:

  • add basic auth security
  • add monitoring
  • add cors headers
  • ...

Create your middleware

You can see example from cors middleware.

To use it simply add it to your RouterFactory.

Here an example

package main
import (
        "github.com/orange-cloudfoundry/gobis"
        log "github.com/sirupsen/logrus"
        "net/http"
)
type TraceConfig struct{
      EnableTrace bool  `mapstructure:"enable_trace" json:"enable_trace" yaml:"enable_trace"`
}
type traceMiddleware struct {}
func (traceMiddleware) Handler(proxyRoute gobis.ProxyRoute, params interface{}, next http.Handler) (http.Handler, error) {
        // Params has been decode route middleware params, this decoded agains schema you gave in schema function
        traceConfig := params.(TraceConfig)
        if !traceConfig.EnableTrace {
            return next, nil
        }
        return TraceHandler(next), nil
}
// Schema function is required in order to gobis to decode params from route and sent it back to handler function through `params`
// It use https://github.com/mitchellh/mapstructure when decode to inject in handler
func (traceMiddleware) Schema() interface{} {
        return TraceConfig{}
}
func TraceHandler(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                groups := gobis.Groups(r) // retrieve current user groups set by other middlewares with gobis.AddGroups(r, "mygroup1", "mygroup2")
                user := gobis.Username(r) // retrieve current user name set by other middlewares with gobis.SetUsername(r, "username")
                path := gobis.Path(r) // retrieve the path which will be passed to upstream (wihtout trailling path name on your route)
                routeName := gobis.RouteName(r) // retrieve the current route name which use this handler
                log.Info("Url received: "+ r.URL.String())
                h.ServeHTTP(w, r)
        })
}
func main(){
        configHandler := gobis.DefaultHandlerConfig{
                StartPath: "/gobis",
                Routes: []gobis.ProxyRoute{
                    {
                        Name: "myapi",
                        Path: "/app/**",
                        Url: "http://www.mocky.io/v2/595625d22900008702cd71e8",
                    },
                },
        }
        log.SetLevel(log.DebugLevel) // set verbosity to debug for logs
        gobisHandler, err := gobis.NewDefaultHandler(
                    configHandler,
                    &traceMiddleware{},
                )
        if err != nil {
                panic(err)
        }
        err = http.ListenAndServe(":8080", gobisHandler)
        if err != nil {
                panic(err)
        }
}

Available middlewares

Middlewares are located on repo https://github.com/orange-cloudfoundry/gobis-middlewares

Running a standalone server

You can run a prepared gobis server with all default middlewares in one command line, see repo https://github.com/orange-cloudfoundry/gobis-server .

This server can be ran on cloud like Kubernetes, Cloud Foundry or Heroku.

Pro tips

You can set multiple middleware params programmatically by using a dummy structure containing each config you wanna set, example:

package main
import (
    "github.com/orange-cloudfoundry/gobis-middlewares/trace"
    "github.com/orange-cloudfoundry/gobis-middlewares/cors"
    "github.com/orange-cloudfoundry/gobis"
)
func main(){
    configHandler := gobis.DefaultHandlerConfig{
            Routes: []gobis.ProxyRoute{
                {
                    Name: "myapi",
                    Path: "/app/**",
                    Url: "http://www.mocky.io/v2/595625d22900008702cd71e8",
                    MiddlewareParams: struct {
                        trace.TraceConfig
                        cors.CorsConfig
                    }{
                        TraceConfig: trace.TraceConfig{
                            Trace: &trace.TraceOptions{
                                Enabled: true,
                            },
                        },
                        CorsConfig: cors.CorsConfig{
                            Cors: &cors.CorsOptions{
                                Enabled: true,
                            },
                        },
                    },
                },
            },
    }
    gobisHandler, err := gobis.NewDefaultHandler(configHandler, trace.NewTrace(), cors.NewCors())
}

FAQ

Why this name ?

Gobis is inspired by zuul which also a kind of dinosaur which come from the family of Ankylosauridae, the gobis(aurus) come also from this family.