Golang → go-chi: Генерация URL по имени роута
Пересадил свой блог с gorilla/mux на go-chi и в процессе переделывания обнаружил два момента:
- В go-chi нет генерации урлов из коробки
- gorilla/mux уже не заброшенный проект, у него появилась новая команда мантейнеров
Последний пункт, в принципе, сделал задачу по замене роутера ненужной, ведь я менял его потому, что gorilla/mux не поддерживается, но меня было уже не остановить, ведь процесс программирования тоже важен, а не только конечный результат 😊
Быстрое гугление по запросу "go-chi generate url by name" привело меня в issue #209, где я наткнулся на пакет reverse от alehano и который походил на то, что я уже задумал сделать для решения этой задачи по генерации урлов. Оставалось только форкнуть этот пакет и модифицировать в соответствии со своим видением, каким этот reverse должен быть → github.com/xelbot/reverse
Приведу пару примеров. Код без реверса, исходный:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main
import (
"net/http"
"supersite/handlers"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
r.Get("/article/{slug}", handlers.ArticleAction)
r.Get("/avatar/{hash:[0-9A-Z]+}.png", handlers.Avatar)
http.ListenAndServe(":8000", r)
}
|
Этот же фрагмент, но уже с реверсом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package main
import (
"net/http"
"supersite/handlers"
"github.com/go-chi/chi/v5"
"github.com/xelbot/reverse"
)
func main() {
r := chi.NewRouter()
r.Get(reverse.Add("article", "/article/{slug}"), handlers.ArticleAction)
r.Get(reverse.Add("avatar", "/avatar/{hash:[0-9A-Z]+}.png"), handlers.Avatar)
http.ListenAndServe(":8000", r)
}
|
Генерация урла происходит в стиле gorilla/mux, с передачей имени роута и строковыми парами имя параметра/значение:
1 2 3 4 5 6 7 8 9 10 11 12 13 | url, err := reverse.Get("article", "slug", "url-generation")
if err != nil {
panic(err)
}
// url: /article/url-generation
url2, err := reverse.Get("avatar", "hash", "A3B2C1")
if err != nil {
panic(err)
}
// url2: /avatar/A3B2C1.png
|
Поддерживаются и суброуты, т.е. группы роутов, с общим префиксом:
1 2 3 4 5 6 7 8 9 10 11 | r := chi.NewRouter()
r.Route(reverse.Group("group-art", "/articles"), func(r chi.Router) {
r.Get(reverse.AddGr("search", "group-art", "/search"), searchArticles)
r.Get(reverse.AddGr("article", "group-art", "/{year}/{slug:[a-z-]+}"), getArticle)
})
url1, _ := reverse.Get("search")
url2, _ := reverse.Get("article", "slug", "hi-there", "year", "2024")
// url1: /articles/search
// url2: /articles/2024/hi-there
|
Комментарии