Регистрация маршрутов к центральному объекту в Go

Я работаю над простым Go REST API, используя Mux. В большинстве учебных пособий, которые я нашел, предлагается создать маршрутизатор следующим образом:

  • routes.go файл, который содержит глобальный массив всех маршрутов и всех обработчиков маршрутов.
  • router.go файл, который создает объект маршрутизатора, перебирает глобальный массив и регистрирует все на маршрутизаторе.

Я бы лучше использовал другую модель:

  • router.go файл создает экземпляр объекта маршрутизатора и имеет RegisterRoute функция
  • Каждый файл, представляющий отдельный объект или компонент API, может вызывать RegisterRoute и добавьте дополнительные маршруты к маршрутизатору.

Я понятия не имею, как это сделать, потому что, кажется, требует создания функции инициализации для каждого файла и вызова его из main() (который побеждает цель). Есть ли принятый способ сделать это?

1 ответ

Решение

Ты можешь использовать func init(), Это специальная функция, которая вызывается непосредственно перед выполнением программы, во время инициализации пакета.

Вот пример того, как добиться того, чего вы хотите, используя gorilla / mux router, хотя это можно сделать с помощью любой другой библиотеки mux.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/mux"
)

// main.go

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

var routes []Route

func registerRoute(route Route) {
    routes = append(routes, route)
}

func main() {
    router := mux.NewRouter().StrictSlash(false)
    for _, route := range routes {
        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(route.HandlerFunc)
    }

    if err := http.ListenAndServe(":8080", router); err != nil {
        log.Fatalln(err)
    }
}

// index.go
func init() {
    registerRoute(Route{
        "index",
        "GET",
        "/",
        func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "welcome")
        },
    })
}

// users.go
func init() {
    registerRoute(Route{
        "listUsers",
        "GET",
        "/users",
        listUsers,
    })
}

func listUsers(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "users list")
}

// products.go
func init() {
    registerRoute(Route{
        "listProducts",
        "GET",
        "/products",
        listProducts,
    })
}

func listProducts(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "products list")
}

Этот шаблон используется Голангом, например, database/sql а также image пакеты. Вы можете прочитать немного больше об этом здесь: https://www.calhoun.io/why-we-import-packages-we-dont-actually-use-in-golang/

Другие вопросы по тегам