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

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

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

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

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

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


person Noamyoungerm    schedule 17.12.2016    source источник
comment
Ну а если (а в том, что я не уверен) я понимаю вашу проблему, то func init() это то, что вы ищете.   -  person Volker    schedule 17.12.2016


Ответы (1)


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

Вот пример того, как добиться желаемого с помощью маршрутизатора gorilla/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")
}

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

person nvartolomei    schedule 17.12.2016