2015-12-31 17 views
6

i Gorilla Mux bin mit einem REST-API für das Schreiben, und ich habe Probleme meine Routen zu organisieren, zur Zeit alle meine Routen sind in der main.go Datei definiert wie dieseWie organisiert man Gorilla Mux Routen?

//main.go 
package main 

import (
    "NovAPI/routes" 
    "fmt" 
    "github.com/gorilla/mux" 
    "net/http" 
) 

func main() { 

    router := mux.NewRouter().StrictSlash(true) 

    router.HandleFunc("/hello", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Hello") 
    }) 

    router.HandleFunc("/user", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "User") 
    }) 

    router.HandleFunc("/route2", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Route2") 
    }) 

    router.HandleFunc("/route3", func(res http.ResponseWriter, req *http.Request) { 
     fmt.Fprintln(res, "Route3") 
    }) 

    // route declarations continue like this 

    http.ListenAndServe(":1128", router) 

} 

so, was ich tun möchte, ist herausnehmen und Teilen Sie diese Routenerklärung in mehrere Dateien auf, wie würde ich das machen? danke im voraus.

Antwort

5

Was ist mit so etwas?

//main.go 
package main 

import (
    "NovAPI/routes" 
    "fmt" 
    "github.com/gorilla/mux" 
    "net/http" 
) 

func main() { 

    router := mux.NewRouter().StrictSlash(true) 

    router.HandleFunc("/hello", HelloHandler) 
    router.HandleFunc("/user", UserHandler) 
    router.HandleFunc("/route2", Route2Handler) 
    router.HandleFunc("/route3", Route3Handler) 
    // route declarations continue like this 

    http.ListenAndServe(":1128", router) 

} 

func HelloHandler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Hello") 
} 

func UserHandler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "User") 
} 

func Route2Handler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Route2") 
} 

func Route3Handler(res http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(res, "Route3") 
} 

So können Sie Ihre Handler in andere Dateien oder sogar andere Pakete setzen.

Wenn Sie Endup mit zusaetzliche Abhängigkeiten wie eine Datenbank, können Sie sogar die Notwendigkeit der globalen var vermeiden einen Konstruktor Trick:

//main.go 

func main() { 
    db := sql.Open(…) 

    //... 

    router.HandleFunc("/hello", NewHelloHandler(db)) 

    //... 
} 

func NewHelloHandler(db *sql.DB) func(http.ResponseWriter, *http.Request) { 
    return func(res http.ResponseWriter, req *http.Request) { 
     // db is in the local scope, and you can even inject it to test your 
     // handler 
     fmt.Fprintln(res, "Hello") 
    } 
} 
+0

Ich habe das aus Gründen der Einfachheit gemacht, aber meine Handler sind eigentlich im routes-Paket definiert, also muss ich noch die Routen aus der Hauptfunktion nehmen – zola

+2

Ich verstehe den Punkt nicht: wie auch immer du bist schreibe deine Routen immer noch irgendwo ... Wenn dein "main" zu lang ist, kannst du vielleicht einen 'NewRouter'-Helfer schreiben, der es für dich initialisiert. – Elwinar

+1

Eine andere Lösung wäre, eine Initialisierungsfunktion in Ihrem Routenpaket zu haben, die den Router als Eingabe nimmt und die Routen nach Bedarf hinzufügt. Aber ich rate dringend davon ab. – Elwinar

1

Ich mag Github in anderen Projekten Check-out zu greifen Ideen auf, wie man mach Sachen, und für diese Fälle schaue ich mir normalerweise zuerst die Docker repo an. Dies ist die Art, wie sie es tun:

Für die system ‚s Routen, alle Handler in system_routes.go definiert und dann diese Routen auf einer NewRouter Funktion in system.go initialisieren.

type systemRouter struct { 
    backend Backend 
    routes []router.Route 
} 

func NewRouter(b Backend) router.Router { 
    r := &systemRouter{ 
     backend: b, 
    } 

    r.routes = []router.Route{ 
     local.NewOptionsRoute("/", optionsHandler), 
     local.NewGetRoute("/_ping", pingHandler), 
     local.NewGetRoute("/events", r.getEvents), 
     local.NewGetRoute("/info", r.getInfo), 
     local.NewGetRoute("/version", r.getVersion), 
     local.NewPostRoute("/auth", r.postAuth), 
    } 

    return r 
} 

// Routes return all the API routes dedicated to the docker system. 
func (s *systemRouter) Routes() []router.Route { 
    return s.routes 
} 

Beachten Sie, dass systemRouter implementiert die router.Router Schnittstelle und die Routen-Funktion gibt einen [] router.Route und ihre Handler sind definiert als

func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error 

statt Gos Standard http-Handler:

func(w http.ResponseWriter, r *http.Request) 

Es gibt also zusätzlichen Code von ihnen, um einen Docker API Handler zu einem Go HTTP Handler bei der makeHttpHandler Funktion zu konvertieren.

Und schließlich, um diese Routen zu ihrem Mux-Router hinzufügen, auf ihrer server.go implementieren sie mehrere andere Funktionen zu add middleware an ihre Handler.

Wenn dies etwas ist, das Sie denken, dass es das ist, was Sie suchen, dann nehmen Sie sich Zeit, den Docker Code für ihre Routen zu analysieren, und wenn Sie mich mehr ausarbeiten oder etwas verpasst haben, schreiben Sie einen Kommentar.

Verwandte Themen