API возвращает только последнюю строку для вложенной структуры - PullRequest
1 голос
/ 19 мая 2019

Я создал REST API Golang. Другие HTTP-глаголы работают хорошо, кроме GET, который выбирает все из базы данных.

У меня есть вложенная структура для модели, как показано ниже:

type Config struct {
    ID   int    `json:"id"`
    Name string `json:"name,omitempty"`
    Data *Data  `json:"data,omitempty"`
}

type Data struct {
    Host     string `json:"host,omitempty"`
    Database string `json:"database,omitempty"`
    Password string `json:"password,omitempty"`
    Username string `json:"username,omitempty"`
    Engine   string `json:"engine,omitempty"`
}

Я делаю JSON unmarshal против Данных. Смотрите код ниже:

model.go

func List(db *sql.DB, start, count int) ([]Config, error) {
    var dt string
    var c Config
    rows, err := db.Query(
        "SELECT * FROM configs LIMIT $1 OFFSET $2",
        count, start)

    if err != nil {
        return nil, err
    }

    defer rows.Close()

    configs := []Config{}

    for rows.Next() {
        //var c Config
        if err := rows.Scan(&c.ID, &c.Name, &dt); err != nil {
            return nil, err
        }
        json.Unmarshal([]byte(dt), &c.Data)
        // for _, p := range c.Data {
        //  configs = append(configs, c)
        // }
        configs = append(configs, c)
    }

    return configs, nil
}

controller.go

func (a *App) getConfigs(w http.ResponseWriter, r *http.Request) {
    count, _ := strconv.Atoi(r.FormValue("count"))
    start, _ := strconv.Atoi(r.FormValue("start"))

    if count > 10 || count < 1 {
        count = 10
    }
    if start < 0 {
        start = 0
    }

    configs, err := List(a.DB, start, count)
    fmt.Print(configs)

    if err != nil {
        fatalError(w, http.StatusInternalServerError, err.Error())
        return
    }

    jsonResponse(w, http.StatusOK, configs)
}

Когда я нажимаю на конечную точку get, я получаю следующее:

[
    {
        "id": 2,
        "name": "test2",
        "data": {
            "host": "newhosty",
            "database": "locau",
            "password": "poy",
            "username": "psq",
            "engine": "dgnewy"
        }
    },
    {
        "id": 3,
        "name": "test3",
        "data": {
            "host": "newhosty",
            "database": "locau",
            "password": "poy",
            "username": "psq",
            "engine": "dgnewy"
        }
    },
    {
        "id": 4,
        "name": "test39",
        "data": {
            "host": "newhosty",
            "database": "locau",
            "password": "poy",
            "username": "psq",
            "engine": "dgnewy"
        }
    }
]

Как видите, часть json data дублируется для всех id. Только name и id работают как положено. Я ожидал, что все данные будут разными, как в БД. Похоже, он выбирает только последнюю строку для части данных.

Что-то я делаю не так?

1 Ответ

2 голосов
/ 19 мая 2019

Я исправил это, заменив Data *Data на Data Data.Проблема была в том, что когда json.Unmarshal заполняет c.Data, он видит, что в нем уже есть структура, и перезаписывает ее.

...