Skip to content
New issue

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

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

Already on GitHub? # 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
}

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

No branches or pull requests

2 participants