在Go中注册路由到中央对象

huangapple go评论92阅读模式
英文:

Registering Routes to Central Object in Go

问题

我正在开发一个简单的Go REST API,使用Mux库。大部分教程都建议按照以下方式创建路由器:

  • 一个routes.go文件,其中包含一个全局数组,包含所有的路由和路由处理函数。
  • 一个router.go文件,创建一个路由器对象,并循环遍历全局数组,将所有路由注册到路由器中。

我更愿意使用另一种模式:

  • 一个router.go文件实例化一个路由器对象,并拥有一个RegisterRoute函数。
  • 每个文件代表API的不同对象或组件,可以调用RegisterRoute函数,并向路由器添加额外的路由。

我不知道如何做到这一点,因为它似乎需要为每个文件创建一个初始化函数,并从main()函数中调用它(这违背了初衷)。有没有一种被广泛接受的方法来实现这个?

英文:

I'm working on a simple Go REST API, using Mux. Most of the tutorials I've found suggested creating the router as follows:

  • A routes.go file which contains a global array of all routes and all route handlers.
  • A router.go file which creates a router object and loops over the global array and registers everything to the router.

I'd rather use a different model:

  • A router.go file instantiates a router object and has a RegisterRoute function
  • Each file, representing a different object or component of the API, can call RegisterRoute and add additional routes to the router.

I have no idea how to do this, because it seems to require creating an initialization function for each file and calling it from main() (which defeats the purpose). Is there any accepted way to do this?

答案1

得分: 8

你可以使用func init()。这是一个特殊的函数,在程序执行之前、包初始化期间被调用。

以下是使用gorilla/mux路由器实现你想要的功能的示例,尽管也可以使用其他任何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")
}

这种模式在Go语言中被database/sqlimage等包使用。你可以在这里阅读更多相关信息:https://www.calhoun.io/why-we-import-packages-we-dont-actually-use-in-golang/

英文:

You can use func init(). It is a special function which is called right before program execution, during package initialization.

Here is an example of how to achieve what you want using gorilla/mux router, though it can be achieved with any other mux library.

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

This pattern is used by golang for example by database/sql and image packages. You can read a little bit more about this here: https://www.calhoun.io/why-we-import-packages-we-dont-actually-use-in-golang/

huangapple
  • 本文由 发表于 2016年12月17日 20:15:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/41198483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定