草庐IT

mongodb - 在 Golang 和 MongoDB 中将路由拆分为单独的包

coder 2023-07-01 原文

我是 Golang 的新手,我已经在 Golang 和 MongoDB 中创建了一个 api。 经过艰苦的努力,成功地将 Controller 和模型包分开,现在我想在一个单独的路由器包中定义路由,并像 Controller ​​和模型一样在主包中访问它们。我正在使用 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)
}

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

模型/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"` 
 } 

最佳答案

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

路线/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

...等等。

如你所见,它们都属于包路由,但分为多个文件。文件名实际上并不重要。您可以根据需要命名它们。 模型位于models 目录中,也属于单个package models 包。 每次创建新的路由文件时,记得在 routes.go 文件中调用它。

希望这对某些人有所帮助。

关于mongodb - 在 Golang 和 MongoDB 中将路由拆分为单独的包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31086315/

有关mongodb - 在 Golang 和 MongoDB 中将路由拆分为单独的包的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  5. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  6. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  7. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  8. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

  9. ruby-on-rails - 使用包含多个关联和单独的条件 - 2

    我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS

  10. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

随机推荐