将路由拆分为独立的包在Golang和MongoDB中。

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

split routes into separate package in Golang and MongoDB

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我刚开始学习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)
}

controllers/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 &NoteController{s}
}

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.NotesResource{Notes: 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(&noteResource)
	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(&note)
	if err != nil {
		panic(err)
	} else {
		log.Printf("Inserted New Record with Title :%s", note.Title)
	}
	j, err := json.Marshal(models.NoteResource{Note: 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(&noteResource)
	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:"createdOn"`
}

type NoteResource struct {
	Note Note `json:"note"`
}

type NotesResource struct {
	Notes []Note `json:"notes"`
}

希望对你有帮助!

英文:

I'm new to Golang, i have been created an api in Golang and MongoDB.
After a hard struggle successfully separate the controller and model packages ,Now i want to define routes in a separate package of routers and access them in main package same like controllers and models.I'm using gorilla/mux package for routing.Anyone can help me please, thanks in Advance!
and here is all of my code:

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

controllers/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 &NoteController{s}
}
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.NotesResource{Notes: 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(&noteResource)
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(&note)
if err != nil {
panic(err)
} else {
log.Printf("Inserted New Record with Title :%s", note.Title)
}
j, err := json.Marshal(models.NoteResource{Note: 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(&noteResource)
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"` 
} 

答案1

得分: 2

我不是一个编程专家,但这是我管理路由/处理程序的方式。

routes/routes.go

package routes
import (
"github.com/gorilla/mux"
)
// NewRouter是主要的路由入口点
func NewRouter() *mux.Router {
r := mux.NewRouter()
indexHandler(r)  // 首页处理程序
fileServer(r) // 文件服务器用于提供静态文件
otherLogicalHandler(r) // 其他领域/业务逻辑范围的处理程序
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")
// 如果要在当前的indexHandler.go文件中列出其他端点,可以在此处添加
// 例如:r.HandleFunc("/signup", signupMainHandler).Methods("GET")
}
// 处理程序
func indexMainHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
// 在此处调用您的模型
mydata, err := models.GetMyDataFunction()
if err != nil {
// 在此处处理错误
return
}
utils.ExecuteTemplate(w, "index.html", struct {
Title                 string
// 在模板中使用您的模型数据
MyData             []models.MyData
// 如果每个页面使用多个数据对象,则可以在此处添加其他模型/数据。
}{
Title: "主页",
MyData:             mydata,
})
}
// func signupMainHandler(w http.ResponseWriter, r *http.Request) ...
// 基本上与indexMainHandler函数中的逻辑相同

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文件中调用它。

希望对某些人有所帮助。

英文:

Not an programming expert but this is how I manage my routes/handlers.

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

... and so on.

As you can see, all they belong to package routes but are divided into multiple files. File names doesn't actually matter. You can name them as you want.
Models lives in models directory and also belongs to single package models package.
Every time you create new routes file, remember to call it in routes.go file.

Hope this will help for somebody.

huangapple
  • 本文由 发表于 2015年6月27日 15:33:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/31086315.html
匿名

发表评论

匿名网友

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

确定