2017-02-13 19 views
0

我很新,去嘗試學習,我正在用杜松子酒的服務器設置一個應用程序。 我設法讓它與主包中的所有東西一起工作,我想更好地組織一個包(我管理)中的所有最相關的,並通過文件拆分每個組CRUD。golang gin-gonic和包中的文件拆分

所以在初始化函數內包的「主」的文件,我定義爲:

Router := gin.New() 
Router.Use(gin.Logger()) 
Router.Use(gin.Recovery()) 

和我,雖然我將能夠在包中使用它這樣的互相文件:

v1 := Router.Group("/api/v1/todos") 
v1.Use(AuthRequired()) 
{ 
    v1.POST("/", CreateTodo) 
    v1.GET("/", FetchAllTodo) 
    v1.GET("/:id", FetchSingleTodo) 
    v1.PUT("/:id", UpdateTodo) 
    v1.DELETE("/:id", DeleteTodo) 
} 

packagename.Router.Group 

但都不是工作,我得到:

undefined: Router in Router.Group

stéphane PS:我確實爲軟件包設置了一個子文件夾,如果它在一個文件中,我就可以構建它。


我雖然該解決方案是路由器變量聲明爲* gin.Engine但同時它編譯罰款,我上Router.Group呼叫恐慌錯誤

讓我發表一些部分的代碼:

maincode.go:

package main 

import (
    "fmt" 
    "./apirest" 
    "github.com/braintree/manners" 
) 

func main(){ 
    fmt.Printf("hello world.\n") 
    //router.Run() 
    manners.ListenAndServe(":8080", apirest.Router) 
} 

然後我在2個文件分割apirest包:

apirest.go(我做了人工清理,梅比我錯過了一個進口):是處理所有申報

package apirest 

import (
    "fmt" 
    "github.com/gin-gonic/gin" 
    "github.com/braintree/manners" 
    "os" 
    "os/signal" 
) 

//Router pour gérer l'api 
var Router *gin.Engine 

/* 
    MAIN FUNCTION 
*/ 
func init() { 

    Router := gin.New() 
    Router.Use(gin.Logger()) 
    Router.Use(gin.Recovery()) 

    c := make(chan os.Signal, 1) 
    signal.Notify(c, os.Interrupt) 
    go func(){ 
     for sig := range c { 
      // sig is a ^C, handle it 
      fmt.Printf("ctl+c catched "+sig.String()) 
      manners.Close() 
     } 
    }() 

    LoadMonitor() 

} 

,然後todoCRUD.go文件時,todoCRUD.go和apirest.go是在同一子文件夾apirest(和編譯OK):

package apirest 

import (
    "fmt" 
    "github.com/gin-gonic/gin" 
    "gopkg.in/validator.v2" 
    "github.com/jinzhu/gorm" 
    "strconv" 
    "net/http" 
    "time" 
) 

//Todo definition d'un element todo 
type Todo struct { 
    gorm.Model 
    CreatedAt time.Time 
    UpdatedAt time.Time 
    OwnerID  int `json:"ownerid" validate:"nonzero"` 
    URL   string `json:"url"` 
} 

//TransformedTodo version pour le retour d'api sans certaines infos 
type TransformedTodo struct { 
    ID   uint `json:"id"` 
    CreatedAt time.Time 
    UpdatedAt time.Time 
    OwnerID  uint `json:"ownerid"` 
    URL   string `json:"url"` 
} 

//LoadTodo permet de lancer le mappage todos 
func LoadTodo(){ 
    v1 := Router.Group("/api/v1/todos") 
    { 
     v1.POST("/", CreateTodo) 
     v1.GET("/", FetchAllTodo) 
     v1.GET("/:id", FetchSingleTodo) 
     v1.PUT("/:id", UpdateTodo) 
     v1.DELETE("/:id", DeleteTodo) 
    } 
} 

//CreateTodo génération d'un todo 
func CreateTodo(c *gin.Context) { 

    owner, _ := strconv.Atoi(c.PostForm("ownerid")) 
    todo := Todo{ 
     OwnerID: owner, 
     URL: c.PostForm("url"), 
    }; 
    v := validator.NewValidator() 
    if errs := v.Validate(todo); errs!=nil { 
     errors := errs.(validator.ErrorMap) 
     var errOuts []string 
     for f, e := range errors { 
      errOuts = append(errOuts, fmt.Sprintf("\t - %s (%v)\n", f, e)) 
     } 
     //c.JSON(500, gin.H{"Error": errs.Error()}) 
     c.JSON(500, gin.H{"Erreur sur le(s) champ(s) : ": errOuts}) 
    } else { 

     db, _ := Database() 
     defer db.Close() 
     db.Save(&todo) 

     c.JSON(http.StatusCreated, gin.H{"status" : http.StatusCreated, "message" : "Todo item created successfully!", "resourceId": todo.ID}) 
    } 
} 

//FetchAllTodo récupération de tous les todos 
func FetchAllTodo(c *gin.Context) { 
    var todos []Todo 
    var _todos []TransformedTodo 

    db, _ := Database() 
    defer db.Close() 
    db.Find(&todos) 

    if (len(todos) <= 0) { 
     c.JSON(http.StatusNotFound, gin.H{"status" : http.StatusNotFound, "message" : "No todo found!"}) 
     return 
    } 

    //transforms the todos for building a good response, 
    //je peux choisir des champs a ne pas display 
    for _, item := range todos { 
     status := false 
     if (item.Status == 1) { 
      status = true 
     } else { 
      status = false 
     } 
     _todos = append(_todos, TransformedTodo{ID: item.ID, URL:item.URL}) 
    } 
    c.JSON(http.StatusOK, gin.H{"status" : http.StatusOK, "data" : _todos}) 
} 

//FetchSingleTodo Récupération d'un seul todo en fonction de son id 
func FetchSingleTodo(c *gin.Context) { 
    var todo Todo 
    todoID := c.Param("id") 

    db, _ := Database() 
    defer db.Close() 
    db.First(&todo, todoID) 

    if (todo.ID == 0) { 
     c.JSON(http.StatusNotFound, gin.H{"status" : http.StatusNotFound, "message" : "No todo found!"}) 
     return 
    } 

    _todo := TransformedTodo{ID: todo.ID, URL:todo.URL} 
    c.JSON(http.StatusOK, gin.H{"status" : http.StatusOK, "data" : _todo}) 
} 

//UpdateTodo Mise à jour d'un todo 
func UpdateTodo(c *gin.Context) { 
    var todo Todo 
    todoID := c.Param("id") 
    db, _ := Database() 
    defer db.Close() 
    db.First(&todo, todoID) 

    if (todo.ID == 0) { 
     c.JSON(http.StatusNotFound, gin.H{"status" : http.StatusNotFound, "message" : "No todo found!"}) 
     return 
    } 

    db.Model(&todo).Update("title", c.PostForm("title")) 
    db.Model(&todo).Update("completed", c.PostForm("completed")) 
    c.JSON(http.StatusOK, gin.H{"status" : http.StatusOK, "message" : "Todo updated successfully!"}) 
} 


//DeleteTodo Suppression d'un todo 
func DeleteTodo(c *gin.Context) { 
    var todo Todo 
    todoID := c.Param("id") 
    db, _ := Database() 
    defer db.Close() 
    db.First(&todo, todoID) 

    if (todo.ID == 0) { 
     c.JSON(http.StatusNotFound, gin.H{"status" : http.StatusNotFound, "message" : "No todo found!"}) 
     return 
    } 

    db.Delete(&todo) 
    c.JSON(http.StatusOK, gin.H{"status" : http.StatusOK, "message" : "Todo deleted successfully!"}) 
} 

的想法是在同一個包爲每個實體xxxxCRUD.go文件來處理,但整個文件夾。

確切errror是:

PS D:\www\developpement> go run .\maincode.go [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode)

panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x0 pc=0x46cc0f]

goroutine 1 [running]: panic(0x831880, 0xc04200a080) C:/Go/src/runtime/panic.go:500 +0x1af /D/www/developpement/apirest.LoadTodo() D:/www/developpement/apirest/todoCRUD.go:33 +0x2f [Router.Group] /D/www/developpement/apirest.init.1() D:/www/developpement/apirest/apirest.go:73 +0x220 [LoadTodo()] /D/www/developpement/apirest.init() D:/www/developpement/apirest/todoCRUD.go:190 +0x80 [last line] main.init() D:/www/developpement/maincode.go:13 +0x3a [manners.ListenAndServe(":8080", apirest.Router)] exit status 2

我希望這將有助於瞭解!

感謝您的時間和幫助!

斯特凡

+0

你能爲此提供您的非工作源? (考慮到你的解釋,一切似乎都是按順序的) – Niko

回答

1

我還是設法使其由 「送」 中LoadTodo功能路由器工作:

在apirest.go

LoadTodo(Router) 

和todoCRUD。去:

func LoadTodo(r *gin.Engine){ 

和它的正常工作......我希望我沒有帶來代碼中的錯誤失敗...

斯特凡