Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Middleware per route with the "chi" library #113

Open
sneko opened this issue Feb 11, 2022 · 1 comment
Open

Middleware per route with the "chi" library #113

sneko opened this issue Feb 11, 2022 · 1 comment

Comments

@sneko
Copy link

sneko commented Feb 11, 2022

Hi @slok ,

When using http directly I do see how to set a specific handlerID for each route:
https://github.com/slok/go-http-metrics/blob/master/examples/custom/main.go#L54-L57

But in the chi example there is none:
https://github.com/slok/go-http-metrics/blob/master/examples/chi/main.go

Since your library seems not able take as entry a HandleFunc to return a HandleFunc, I guess I have to manage it with a more complex way with chi. Something like:

	r := chi.NewRouter()

	recorder := metrics.NewRecorder(metrics.Config{
		Registry:        reg,
		Prefix:          "exampleapp",
		DurationBuckets: []float64{1, 2.5, 5, 10, 20, 40, 80, 160, 320, 640},
	})
	mdlw := middleware.New(middleware.Config{
		Recorder:      recorder,
		GroupedStatus: true,
	})

	// Specific route
	r.Group(func(r chi.Router) {
		r.Use(std.HandlerProvider("my_specific_route", mdlw))

		r.Post("/", aaaaaaa)
	})

	return r

Is there a more simple way than embedding all my registered routes with Post / Get / ... inside individual groups?

Thank you,

@slok
Copy link
Owner

slok commented Feb 11, 2022

Hi @sneko

EDIT: Nevermind Its the same in the end, So I'm afraid... no, there isn't a simpler way :/ sorry

I'm not a chi user myself, but this would work for you? (I used the example that go-http-metrics has):

package main

import (
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/go-chi/chi"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	metrics "github.com/slok/go-http-metrics/metrics/prometheus"
	"github.com/slok/go-http-metrics/middleware"
	"github.com/slok/go-http-metrics/middleware/std"
)

const (
	srvAddr     = ":8080"
	metricsAddr = ":8081"
)

func main() {
	// Create our middleware.
	mdlw := middleware.New(middleware.Config{
		Recorder: metrics.NewRecorder(metrics.Config{}),
	})

	// Create our router with the metrics middleware.
	r := chi.NewRouter()

	// Add paths.
	r.Route("/", func(r chi.Router) {
		r.Use(std.HandlerProvider("root", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			time.Sleep(200 * time.Millisecond)
			w.WriteHeader(http.StatusOK)
		})
	})

	r.Route("/test1", func(r chi.Router) {
		r.Use(std.HandlerProvider("custom-id-test1", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) })
	})
	r.Route("/test1/test2", func(r chi.Router) {
		r.Use(std.HandlerProvider("custom-id-test12", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusAccepted) })
	})
	r.Route("/test1/test4", func(r chi.Router) {
		r.Use(std.HandlerProvider("custom-id-test14", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNonAuthoritativeInfo) })
	})
	r.Route("/test2", func(r chi.Router) {
		r.Use(std.HandlerProvider("custom-id-test2", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })
	})
	r.Route("/test3", func(r chi.Router) {
		r.Use(std.HandlerProvider("custom-id-test3", mdlw))
		r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusResetContent) })
	})

	// Serve our handler.
	go func() {
		log.Printf("server listening at %s", srvAddr)
		if err := http.ListenAndServe(srvAddr, r); err != nil {
			log.Panicf("error while serving: %s", err)
		}
	}()

	// Serve our metrics.
	go func() {
		log.Printf("metrics listening at %s", metricsAddr)
		if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
			log.Panicf("error while serving metrics: %s", err)
		}
	}()

	// Wait until some signal is captured.
	sigC := make(chan os.Signal, 1)
	signal.Notify(sigC, syscall.SIGTERM, syscall.SIGINT)
	<-sigC
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants