jmm
jmm

Reputation: 1064

Panic error when trying to serve a Gin Gonic app

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:

project structure

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

Answers (1)

Motakjuq
Motakjuq

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

Related Questions