Reputation: 1064
I'm trying to create a small API using Gin framework for Go, and I'm getting an error when trying to split it in many files. Since I'm an absolute beginner in Go, I'm probably doing some big stupid mistake, so please bear with me :)
My project structure is this:
models.go
package models
type Note struct {
Title string `form:"title" json:"title" binding:"required"`
Body string `form:"body" json:"body" binding:"required"`
}
var Notes []Note
func MockData() {
Notes = append(Notes, Note{Title: "My first note", Body: "Brazil beated Argentina very badly :("})
Notes = append(Notes, Note{Title: "Some more notes", Body: "I hope we can defeat Colombia"})
}
url_mappings.go
package mappings
import (
"gopkg.in/gin-gonic/gin.v1"
"github.com/juanmougan/notepad/api/controllers"
)
var Router *gin.Engine
func CreateUrlMappings() {
Router := gin.Default()
// v1 of the API
v1 := Router.Group("/v1")
{
v1.GET("/notes", controllers.AllNotesEndpoint)
}
}
main.go
package main
import (
"github.com/juanmougan/notepad/api/models"
"github.com/juanmougan/notepad/api/mappings"
)
func main() {
// TODO eventually use a real DB
models.MockData()
mappings.CreateUrlMappings()
// Listen and server on 0.0.0.0:8080
mappings.Router.Run(":8080")
}
notes_controllers.go
package controllers
import (
"gopkg.in/gin-gonic/gin.v1"
"net/http"
"github.com/juanmougan/notepad/api/models"
)
func AllNotesEndpoint(c *gin.Context) {
c.JSON(http.StatusOK, models.Notes)
}
When I run the app, it seems to start Ok
MacBook-Pro-de-Juan:notepad juanma$ go run api/main/main.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)
[GIN-debug] GET /v1/notes --> github.com/juanmougan/notepad/api/controllers.AllNotesEndpoint (3 handlers)
[GIN-debug] Listening and serving HTTP on :8080
But when trying to navigate to http://localhost:8080/v1/notes
, I get this error:
http: panic serving [::1]:50178: runtime error: invalid memory address or nil pointer dereference
goroutine 35 [running]:
net/http.(*conn).serve.func1(0xc420166400)
/usr/local/opt/go/libexec/src/net/http/server.go:1491 +0x12a
panic(0x396220, 0xc42000c0b0)
/usr/local/opt/go/libexec/src/runtime/panic.go:458 +0x243
gopkg.in/gin-gonic/gin%2ev1.(*Engine).ServeHTTP(0x0, 0x5a7c80, 0xc4201ec0d0, 0xc4200f0870)
/Users/juanma/.go/src/gopkg.in/gin-gonic/gin.v1/gin.go:260 +0x26
net/http.serverHandler.ServeHTTP(0xc420166380, 0x5a7c80, 0xc4201ec0d0, 0xc4200f0870)
/usr/local/opt/go/libexec/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc420166400, 0x5a83c0, 0xc420174440)
/usr/local/opt/go/libexec/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
/usr/local/opt/go/libexec/src/net/http/server.go:2293 +0x44d
http: panic serving [::1]:50179: runtime error: invalid memory address or nil pointer dereference
goroutine 36 [running]:
net/http.(*conn).serve.func1(0xc420166600)
/usr/local/opt/go/libexec/src/net/http/server.go:1491 +0x12a
panic(0x396220, 0xc42000c0b0)
/usr/local/opt/go/libexec/src/runtime/panic.go:458 +0x243
gopkg.in/gin-gonic/gin%2ev1.(*Engine).ServeHTTP(0x0, 0x5a7c80, 0xc420214000, 0xc4200f0960)
/Users/juanma/.go/src/gopkg.in/gin-gonic/gin.v1/gin.go:260 +0x26
net/http.serverHandler.ServeHTTP(0xc420166380, 0x5a7c80, 0xc420214000, 0xc4200f0960)
/usr/local/opt/go/libexec/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc420166600, 0x5a83c0, 0xc420174600)
/usr/local/opt/go/libexec/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
/usr/local/opt/go/libexec/src/net/http/server.go:2293 +0x44d
Which is strange, because I don't see any reference to my own code. I have found some similar questions, like this, but all of them seem to have errors on their own code at the top of the stack trace. For I can see, I'm only getting framework errors.
Any ideas on what could be going wrong here?
Thanks in advance
Upvotes: 0
Views: 2639
Reputation: 2259
Change the initialization on mappings
var Router *gin.Engine
func CreateUrlMappings() {
Router = gin.Default()
// v1 of the API
v1 := Router.Group("/v1")
{
v1.GET("/notes", controllers.AllNotesEndpoint)
}
}
You're creating a new local variable when you use ":=" operator
Router := gin.Default() // this is wrong if you are using a global var
Upvotes: 1