Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

350 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Custom Router and Handler v1.11.1

Advantages

Injection of middlewares

type Middleware interface {
  Apply(f HandlerFunc) HandlerFunc
}
type MiddlewareFunc func(HandlerFunc) HandlerFunc

Middleware as a struct:

type MyMiddleware struct {
  SomeData string
}

func(m *MyMiddleware) Apply(h HandlerFunc) HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, vars map[string]string) error {
		// Do something before handler
		h(w, r, vars)
		// Do something after handler
	}
}

Or as a function

func MyFunctionMiddleware(h HandlerFunc) HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, vars map[string]string) error {
		// Do something before handler
		h(w, r, vars)
		// Do something after handler
	}
}

Add them to your router with:

router.Use(MyMiddleware)
router.Use(MiddlewareFunc(MyMiddleware))

Middlewares have to be setup before setting the handlers.

Error propagation in the middlewares

The handler returns an error which can be read/managed by the middlwares. So you can add your Airbrake or Rollbar notification as a simple middleware.

Testable handlers based on Gorilla Muxer

mux.Vars(req)vars map[string]string argument of Handler

Included middlewares

Logging Middleware

logger := logrus.New()
middleware := NewLoggingMiddleware(logger)
router.Use(middleware)

That being said there when NewRouter it creates a LoggingMiddleware by default.

Cors Middleware

router.Use(MiddlewareFunc(NewCorsMiddleware))

Error Middleware

Thie middleware writes in the logs with the Error log level. To send logs to rollbar, ensure your logger is properly configured with the rollbar hook.

import (
  "gopkg.in/Scalingo/logrus-rollbar.v1"
)

logger := logger.Default(logrus_rollbar.New(0))
router := handlers.NewRouter(logger)
router.Use(MiddlewareFunc(ErrorHandler))

Profiling router (pprof)

This package provides a ready-to-use router exposing Go's net/http/pprof endpoints behind HTTP Basic Auth.

Profiling endpoints are enabled only if all the following environment variables are set:

  • PPROF_ENABLED: true to enable
  • PPROF_USERNAME: username for Basic Auth
  • PPROF_PASSWORD: password for Basic Auth

If one of these variables is missing (or if PPROF_ENABLED is false), the profiling router is returned but has no routes registered (requests will return 404).

Create the router with NewProfilingRouter(ctx) and mount it on your main router.

import (
	"context"
	"net/http"

	"github.com/Scalingo/go-handlers"
	"github.com/Scalingo/go-utils/logger"
)

func main() {
	log := logger.Default()
	ctx := logger.ToCtx(context.Background(), log)

	router := handlers.NewRouter(log)

	pprofRouter, err := handlers.NewProfilingRouter(ctx)
	if err != nil {
		log.WithError(err).Error("Fail to start profiling routes")
	} else {
		log.Info("Adding profiling routes to the web server")
		// Route all /debug/pprof/* requests to the profiling router.
		router.PathPrefix(handlers.PprofRoutePrefix).Handler(pprofRouter)
	}

	_ = http.ListenAndServe(":8080", router)
}

The profiling endpoints are exposed under handlers.PprofRoutePrefix (currently /debug/pprof).

When enabled, the following endpoints are available under /debug/pprof:

  • / (index)
  • /profile
  • /symbol
  • /cmdline
  • /trace
  • /allocs
  • /heap
  • /mutex
  • /goroutine
  • /threadcreate
  • /block

Example (CPU profile):

go tool pprof -http=:12345 http://PPROF_USERNAME:PPROF_PASSWORD@localhost:8080/debug/pprof/profile?seconds=30

Release a New Version

Bump new version number in CHANGELOG.md and README.md.

Commit, tag and create a new release:

version="1.11.1"

git switch --create release/${version}
git add CHANGELOG.md README.md
git commit --message="Bump v${version}"
git push --set-upstream origin release/${version}
gh pr create --reviewer=Scalingo/team-ist --title "$(git log -1 --pretty=%B)"

Once the pull request merged, you can tag the new release.

Tag the New Release

git tag v${version}
git push origin master v${version}
gh release create v${version}

The title of the release should be the version number and the text of the release is the same as the changelog.

About

Define a custom Handler and router based on gorilla + negroni with easy integration of middlewares

Resources

Stars

4 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages