在 Golang 和 MongoDB 中将路由拆分为单独的包
Posted
技术标签:
【中文标题】在 Golang 和 MongoDB 中将路由拆分为单独的包【英文标题】:split routes into separate package in Golang and MongoDB 【发布时间】:2015-06-27 07:33:25 【问题描述】:我是 Golang 的新手,我已经在 Golang 和 MongoDB 中创建了一个 api。 经过艰苦的努力,成功分离了控制器和模型包,现在我想在单独的路由器包中定义路由,并在主包中访问它们,就像控制器和模型一样。我正在使用 gorilla/mux 包进行路由。任何人都可以提供帮助请给我,在此先感谢! 这是我所有的代码:
RESTMONGOMVC/main.go
package main
import (
"RESTMONGOMVC/controllers"
"log"
"net/http"
"github.com/gorilla/mux"
"gopkg.in/mgo.v2"
)
var (
session *mgo.Session
collection *mgo.Collection
err error
)
func getSession() *mgo.Session
// Connect to our local mongo
s, err := mgo.Dial("mongodb://localhost")
// Check if connection error, is mongo running?
if err != nil
panic(err)
// Deliver session
return s
func main()
var err error
r := mux.NewRouter()
uc := controllers.NewNoteController(getSession())
r.HandleFunc("/api/notes", uc.GetNotes).Methods("GET")
r.HandleFunc("/api/notes", uc.CreateNote).Methods("POST")
r.HandleFunc("/api/notes/id", uc.UpdateNote).Methods("PUT")
r.HandleFunc("/api/notes/id", uc.DeleteNote).Methods("DELETE")
http.Handle("/api/", r)
http.Handle("/", http.FileServer(http.Dir(".")))
log.Println("Starting Mongodb Session")
session, err = mgo.Dial("localhost")
if err != nil
panic(err)
defer session.Close()
session.SetMode(mgo.Monotonic, true)
collection = session.DB("notesdb").C("notes")
log.Println("Listening on 8080")
http.ListenAndServe(":8080", nil)
控制器/note.go
package controllers
import (
"RESTMONGOMVC/models"
"encoding/json"
"log"
"net/http"
"time"
"github.com/gorilla/mux"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
var (
session *mgo.Session
collection *mgo.Collection
err error
)
type (
// UserController represents the controller for operating on the User resource
NoteController struct
session *mgo.Session
)
// NewUserController provides a reference to a UserController with provided mongo session
func NewNoteController(s *mgo.Session) *NoteController
return &NoteControllers
func (uc NoteController) GetNotes(w http.ResponseWriter, r *http.Request)
var notes []models.Note
iter := collection.Find(nil).Iter()
result := models.Note
for iter.Next(&result)
notes = append(notes, result)
w.Header().Set("Content-Type", "application/json")
j, err := json.Marshal(models.NotesResourceNotes: notes)
if err != nil
panic(err)
w.Write(j)
func (uc NoteController) CreateNote(w http.ResponseWriter, r *http.Request)
var noteResource models.NoteResource
err := json.NewDecoder(r.Body).Decode(¬eResource)
if err != nil
panic(err)
note := noteResource.Note
//get a new Id
obj_id := bson.NewObjectId()
note.Id = obj_id
note.CreatedOn = time.Now()
//Insert into document collection
err = collection.Insert(¬e)
if err != nil
panic(err)
else
log.Printf("Inserted New Record with Title :%s", note.Title)
j, err := json.Marshal(models.NoteResourceNote: note)
if err != nil
panic(err)
w.Header().Set("Content-Type", "application/json")
w.Write(j)
func (uc NoteController) UpdateNote(w http.ResponseWriter, r *http.Request)
var err error
//get id from incoming url
vars := mux.Vars(r)
id := bson.ObjectIdHex(vars["id"])
//decode the incoming Note into json
var noteResource models.NoteResource
err = json.NewDecoder(r.Body).Decode(¬eResource)
if err != nil
panic(err)
//partial update on mongodb
err = collection.Update(bson.M"_id": id,
bson.M"$set": bson.M
"title": noteResource.Note.Title,
"decription": noteResource.Note.Description,
)
if err == nil
log.Printf("Updated Note : %s", id, noteResource.Note.Title)
else
panic(err)
w.WriteHeader(http.StatusNoContent)
func (uc NoteController) DeleteNote(w http.ResponseWriter, r *http.Request)
var err error
vars := mux.Vars(r)
id := vars["id"]
//Remove from database
err = collection.Remove(bson.M"_id": bson.ObjectIdHex(id))
if err != nil
log.Printf("Could not find the Note %s to delete", id)
w.WriteHeader(http.StatusNoContent)
models/note.go
package models
import (
"time"
"gopkg.in/mgo.v2/bson"
)
type Note struct
Id bson.ObjectId `bson:"_id" json:"id"`
Title string `json:"title"`
Description string `json:"description"`
CreatedOn time.Time `json:"craetedOn"`
type NoteResource struct
Note Note `json:"note"`
type NotesResource struct
Notes []Note `json:"notes"`
【问题讨论】:
您可能不想将这些文件拆分为单独的包。 Go 的包是可重用的库(通常是独立的)。不要将它们视为命名空间隔离的手段。 这意味着我不能在单独的文件中定义路由并在另一个文件中使用它们? 你当然可以在不同的文件中定义它们,只是不要试图在不同的“包”中定义它们。 【参考方案1】:不是编程专家,但这就是我管理路线/处理程序的方式。
routes/routes.go
package routes
import (
"github.com/gorilla/mux"
)
//NewRouter is main routing entry point
func NewRouter() *mux.Router
r := mux.NewRouter()
indexHandler(r) // Index handler
fileServer(r) // Fileserver to serve static files
otherLogicalHandler(r) // Other domain/business logic scoped handler
return r
routes/indexHandler.go
package routes
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/myusername/project/models"
)
func indexHandler(r *mux.Router)
r.HandleFunc("/", indexMainHandler).Methods("GET")
// Other endpoints goes there if you want to list it in this current indexHandler.go file
// Example: r.HandleFunc("/signup", signupMainHandler).Methods("GET")
// Handlers
func indexMainHandler(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
// Call your model/s there
mydata, err := models.GetMyDataFunction()
if err != nil
// Handle your error there
return
utils.ExecuteTemplate(w, "index.html", struct
Title string
// Use your model data for templates there
MyData []models.MyData
// Other models/data can go there if multiple data objects used per page.
Title: "Main Page",
MyData: mydata,
)
// func signupMainHandler(w http.ResponseWriter, r *http.Request) ...
// Basically repeat the same logic as in indexMainHandler function
routes/fileServer.go
package routes
import (
"net/http"
"github.com/gorilla/mux"
)
func fileServer(r *mux.Router)
fs := http.FileServer(http.Dir("static"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
routes/otherLogicalHandler.go
...等等。
如您所见,它们都属于package routes
,但又分为多个文件。文件名实际上并不重要。您可以根据需要命名它们。
模型位于models
目录中,也属于单个package models
包。
每次创建新路由文件时,记得在routes.go
文件中调用它。
希望这对某人有所帮助。
【讨论】:
以上是关于在 Golang 和 MongoDB 中将路由拆分为单独的包的主要内容,如果未能解决你的问题,请参考以下文章