HTTP роутер для Go с обработкой ошибок

от автора

BunRouter это чрезвычайно быстрый Golang router с уникальной комбинацией возможностей:

  • Мидлвары (middlewares) позволяют вынести общий функционал из HTTP обработчиков в отдельные функции.

  • Встроенная обработка ошибок позволяет снизить размер HTTP функций и обрабатывать ошибки в мидлварах.

  • Минималистическое и совместимое АПИ, которое не пытается делать все сразу: от обработки статичный файлов до генерации XML (gin.Context и echo.Context грешат этим).

И да, он очень быстр, хотя и уступает роутам использующим fasthttp.

Введение

По умолчанию BunRouter использует слегка улучшенную версию http.HandlerFunc, которая принимает bunrouter.Request и возвращает ошибки:

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(), }) }

Но не пугайтесь, BunRouter также умеет работать и с классическими http.HandlerFunc.

BunRouter поддерживает всего 2 типа параметров в роутах:

  • :param это именованный параметр который совпадает с одним сегментом из пути (текстом между слышами).

  • *param это «звездный» параметр, которые совпадает со всем и всегда должен идти в конце роута.

К примеру, /users/:id совпадает с /users/123 и /users/foo-bar, но не с /users/foo/bar.

Мидлвары

Мидлвары позволяют вынести общий функционал в отдельные функции, к примеру, вы можете написать мидлвар, который логирует обработанные запросы:

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\n", req.Method, req.Route(), err)             // Discard the error.             return nil         }          fmt.Printf("%s %s returned %d\n", req.Method, req.Route(), rec.Code)     } }

Мидлвары затем может использовать следующим образом:

router.Use(middleware).WithGroup(...)  // либо  group = group.Use(middleware)

Обработка ошибок

Как вы уже могли заметить, обработчики BunRouter возвращают ошибки, которые вы затем можете обработать в мидлварах:

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 } }

За деталями обращайтесь к документации по HTTP error handling.

Приоритет роутов

Приоритет роутов зависит от типов параметров и сегментов и не зависит от порядка объявления роутов:

  1. Сначала срабатывают статичные сегменты, к примеру, /users/.

  2. Затем именованные параметры, к примеру, :id.

  3. И в последнюю очередь «звездные» параметры, к примеру, *path.

Для понимания рассмотрим следующие роуты отсортированные по приоритету срабатывания:

  • /users/list — статичный роут.

  • /users/:id — роут с именованным параметром.

  • /users/*path — роут с «звездным» параметром.

Что дальше

Чтобы начать использовать BunRouter, обращайтесь к документации или сразу попробуйте запустить примеры.

BunRouter имеет множестов плагинов, к примеру, OpenTelemetry инструментация, которая поддерживает distributed tracing и метрики.

Используя трейсинг, вы можете мониторить производительность, используя полностью бесплатные tracing tools с открытым кодом.

Вы также можете экспортировать собранные метрики в Prometheus, чтобы затем отобразить их в Grafana.


ссылка на оригинал статьи https://habr.com/ru/post/672250/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *