Gorilla Mux и GORM терпят неудачу

Я следил за этим руководством. о том, как настроить базовый API с PostgreSQL, Gorilla Mux и GORM.

Это мое приложение:

package main

import (
    "encoding/json"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/postgres"
)

var db *gorm.DB


type Ticket struct {
    gorm.Model
    InfoHash string
    Status   *int `gorm:"default:'0'"`
}


func main() {
    router := mux.NewRouter()

    db, err := gorm.Open("postgres", "host=localhost user=user dbname=db_development password=password sslmode=disable")
    db.LogMode(true)

    if err != nil {
        panic(err)
    }
    defer db.Close()

    db.AutoMigrate(&Ticket{})

    router.HandleFunc("/", TicketsIndex).Methods("GET")

    http.ListenAndServe(":3000", router)
}

func TicketsIndex(w http.ResponseWriter, r *http.Request) {
    tickets := []Ticket{}
    db.Find(&tickets)
    json.NewEncoder(w).Encode(&tickets)
}

Проблема в том, что когда я посещаю localhost:3000, сервер просто останавливается без журналов ошибок, просто останавливается и выходит из приложения. Он должен вернуть билеты, хранящиеся в базе данных, в формате JSON.

У меня это работает, если я открою базу данных в своей функции TicketsIndex и закрою ее, например:

func TicketsIndex(w http.ResponseWriter, r *http.Request) {
  db, err := gorm.Open("postgres", "host=localhost user=user dbname=db_development password=password sslmode=disable")
  tickets := []Ticket{}
  db.Find(&tickets)
  json.NewEncoder(w).Encode(&tickets)
  defer db.Close()
}

Но я думаю, что это не правильный путь. Я также пытаюсь переместить этот код в основную функцию и также работает:

tickets := []Ticket{}
db.Find(&tickets)

Поэтому я предполагаю, что это может быть глобальная переменная var db *gormDB, которая не назначается правильно. Что я делаю не так?


person Juan Artau    schedule 26.04.2018    source источник
comment
Когда вы вводите db, err := , вы затеняете глобальную var db локальной переменной функции с именем db, не присваивая значение глобальной. Вам нужно использовать знак равенства для назначения уже определенной переменной. Также означает, что вам нужно будет написать var err error внутри области main.   -  person Alex Guerra    schedule 26.04.2018
comment
Это был ответ, мой друг, я боролся с этим со вчерашнего дня. Напишите свой ответ, чтобы я его принял. Благодарю вас!   -  person Juan Artau    schedule 26.04.2018


Ответы (1)


Когда вы вводите db, err := ..., вы на самом деле затеняете глобальный var db с помощью локальной переменной функции с именем db, а не присваиваете значение глобальной переменной. Вам нужно использовать знак равенства (= против :=) для назначения уже определенной переменной. Это также означает, что вам нужно будет написать var err error внутри основной области перед назначением, так как вы больше не получаете объявление автоматически из :=.

person Alex Guerra    schedule 26.04.2018