Как преобразовать фрагмент структуры в допустимый JSON - PullRequest
0 голосов
/ 16 марта 2019

Я пишу API-интерфейс Golang и клиент, но не могу получить действительный JSON из фрагмента структур API. Результат, который я получаю в моем клиенте, выглядит следующим образом.

[{0 Mark 1234 false} {0 John 3456 false}]

Мне нужен этот JSON, чтобы выглядеть как

[{"id": 0, "name": Mark, "pin": 1234, "active": false} {"id": 0, "name": John, "pin": 3456, "active «ложь}]

Я не могу найти примеров, показывающих мне, как правильно это кодировать, и это не дубликат того, что я могу найти, несмотря на предупреждение, что это так. В то время как мой клиент успешно анализирует JSON обратно в структуру, мне также нужно, чтобы он возвращал JSON клиенту IOS, который запрашивает его. Поток API -> API -> клиент iOS. Я не знаю, как создать JSON из структуры для клиента iOS.

Вот мой код API.

// Employee model
type Employee struct {
    EmployeeID int64  `json:"id"`
    Name       string `json:"name"`
    Pin        int    `json:"pin"`
    Active     bool   `json:"active"`
}

func getEmployees(db *sql.DB, venueID int64) ([]Employee, error) {

    var employee Employee

    var employees []Employee

    query, err := db.Query("SELECT id, name, pin FROM employees WHERE active=1 AND venue_id=? ORDER BY name", venueID)
    if err != nil {
        return employees, err
    }

    defer query.Close()

    for query.Next() {
        err = query.Scan(&employee.EmployeeID, &employee.Name, &employee.Pin)
        if err != nil {
            return employees, err
        }
        employees = append(employees, employee)
    }

    return employees, err
}



func (rs *appResource) listEmployees(w http.ResponseWriter, r *http.Request) {

    var venue Venue

    token := getToken(r)

    fmt.Println(token)

    venue, err := getVenue(rs.db, token)

    if err != nil {
        log.Fatal(err)
        return
    }

    venueID := venue.VenueID

    if !(venueID > 0) {
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    employees, err := getEmployees(rs.db, venueID)

    if err != nil {
        log.Fatal(err)
        return
    }

    fmt.Println(employees[0].EmployeeID)

    employeesJSON, err := json.Marshal(employees)
    if err != nil {
        log.Fatal(err)
        return
    }

    w.Write([]byte(employeesJSON))

}

Вот мой код клиента:

func (rs *appResource) getEmployees(w http.ResponseWriter, r *http.Request) {

    path := rs.url + "/employees"

    fmt.Println(path)

    res, err := rs.client.Get(path)

    if err != nil {
        log.Println("error in get")
        log.Fatal(err)
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    defer res.Body.Close()

    if res.StatusCode == 500 {
        fmt.Printf("res.StatusCode: %d\n", res.StatusCode)
        http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        return

    }

    if res.StatusCode == 404 {
        fmt.Printf("res.StatusCode: %d\n", res.StatusCode)
        http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
        return
    }

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
        http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        return
    }

// here I want to return actual JSON to an iOS client    

    w.WriteHeader(http.StatusOK)
    w.Write([]byte("{ok}"))
}

Ответы [ 3 ]

1 голос
/ 16 марта 2019

То, что ваш код в данный момент печатает, является содержимым структуры, а не JSON.Когда вы печатаете содержимое структуры, по умолчанию вы печатаете только значения в этой структуре.Это означает, что fmt.Println(employees.EmployeeList) будет производить что-то вроде:

[{0 Mark 1234 false} {0 John 3456 false}]

Если вы хотите также печатать значения полей, вам нужно будет добавить формат «глагол» %+v, который будет печатать имена полей.fmt.Printf("%+v\n", employees.EmployeeList) должно напечатать что-то вроде:

[{id:0 name:Mark pin:1234 active:false} {id:0 name:John pin:3456 active:false}]

Я думаю, что вы действительно хотите посмотреть на то, как сделать маршалинг ваших данных обратно в строку JSON, чтобы выписать этот контент обратно для клиента.

0 голосов
/ 16 марта 2019

То, что вам нужно, это дамп json, здесь вы дамп структуры, то, что вы можете сделать со структурой, это сбросить ключ и значение с помощью% + v в Printf, посмотрите здесь: https://golang.org/pkg/fmt/#hdr-Printing.

0 голосов
/ 16 марта 2019

Я на самом деле удивлен тем, что ваш код работает вообще, так как у вас есть 2 неиспользуемые переменные (err, err в listEmployees).любым способом, который должен работать, добавлен fmt.Println, чтобы вы могли видеть результат на консоли

 type Employee struct {
        ID     int    `json:"id"`
        Name   string `json:"name"`
        Pin    int    `json:"pin"`
        Active bool   `json:"active"`
    }

    func (rs *appResource) listEmployees(w http.ResponseWriter, r *http.Request) {
        employees, _:= getEmployees(rs.db)
        employeesJSON, _:= json.Marshal(employees)
        fmt.Ptintln(string(employeesJSON))
        w.Write(employeesJSON)
    }

другой пример выполнения:

func main() {
    emp := Employee{
        ID:     1,
        Name:   "Mark",
        Pin:    1234,
        Active: true,
    }
    if jsn, err := json.Marshal(emp); err == nil {
        fmt.Println(string(jsn))
    } else {
        log.Panic(err)
    }

}

type Employee struct {
    ID     int    `json:"id"`
    Name   string `json:"name"`
    Pin    int    `json:"pin"`
    Active bool   `json:"active"`
}

Вывод:

{"id": 1, "name": "Mark", "pin": 1234, "active": true}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...