An Interest In:
Web News this Week
- March 22, 2024
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
Fast Golang router with error handling
BunRouter is an extremely fast Golang router for Go with unique combination of features:
- Middlewares allow to extract common operations from HTTP handlers into reusable functions.
- Error handling allows to further reduce the size of HTTP handlers by handling errors in middlewares.
- Routes priority enables meaningful matching priority for routing rules: first static nodes, then named nodes, lastly wildcard nodes.
- net/http compatible API which means using minimal API without constructing huge wrappers that try to do everything: from serving static files to XML generation (for example,
gin.Context
orecho.Context
).
And yes, it is fast - see the benchmark results.
Quickstart
BunRouter uses a slightly enhanced version of http.HandlerFunc that accepts a bunrouter.Request
and returns errors that you can handle with middlewares:
import "github.com/uptrace/bunrouter"router := bunrouter.New( bunrouter.Use(reqlog.NewMiddleware()),)router.WithGroup("/api", func(g *bunrouter.Group) { g.GET("/users/:id", debugHandler) g.GET("/users/current", debugHandler) g.GET("/users/*path", debugHandler)})func debugHandler(w http.ResponseWriter, req bunrouter.Request) error { // use req.Request to get *http.Request return bunrouter.JSON(w, bunrouter.H{ "route": req.Route(), "params": req.Params().Map(), })}
But don't worry, BunRouter supports classical HTTP handlers too.
BunRouter supports the following param types in routing rules:
:param
is a named parameter that matches a single path segment (text between slashes).*param
is a wildcard parameter that matches everything and must always be at the end of the route.
Middlewares
Middlewares allow you to extract common functionality into a reusable function, for example, here is how you can write a middleware that logs processed requests:
func middleware(next bunrouter.HandlerFunc) bunrouter.HandlerFunc { // you can initialize the middleware here // Return the middleware. return func(w http.ResponseWriter, req bunrouter.Request) error { rec := httptest.NewRecorder() // Pass the recorder instead of http.ResponseWriter. if err := next(rec, req); err != nil { fmt.Printf("%s %s failed: %s
", req.Method, req.Route(), err) // Discard the error. return nil } fmt.Printf("%s %s returned %d
", req.Method, req.Route(), rec.Code) }}
You can then install the middleware like this:
router.Use(middleware).WithGroup(...)
Error handling
As you may have noticed, BunRouter's handlers return errors which you can then handle in middlewares:
func errorHandler(next bunrouter.HandlerFunc) bunrouter.HandlerFunc { return func(w http.ResponseWriter, req bunrouter.Request) error { // Call the next handler on the chain to get the error. err := next(w, req) switch err := err.(type) { case nil: // no error case HTTPError: // already a HTTPError w.WriteHeader(err.statusCode) _ = bunrouter.JSON(w, err) default: httpErr := NewHTTPError(err) w.WriteHeader(httpErr.statusCode) _ = bunrouter.JSON(w, httpErr) } return err // return the err in case there other middlewares }}
See error handling for details.
Routes priority
Routing rules have matching priority that is based on node types and does not depend on routes definition order:
- Static nodes, for example,
/users/
- Named nodes, for example,
:id
. - Wildcard nodes, for example,
*path
.
The following routes are sorted by their matching priority from the highest to the lowest:
/users/list
./users/:id
./users/*path
.
What's next?
Next, start using Golang router in your next application.
BunRouter comes with many plugins including OpenTelemetry instrumentation that enables distributed tracing. Pick a free tracing tool and start monitoring your app performance.
Original Link: https://dev.to/vmihailenco/fast-golang-router-with-error-handling-3625
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To