Чи пустой http.Request. Тело в рендере. Привязка

Я использую http://github.com/pressly/chi для создания этой простой программы, где я пытаюсь декодировать некоторые JSON из http.Request.Body:

package main

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

    "github.com/pressly/chi"
    "github.com/pressly/chi/render"
)

type Test struct {
    Name string `json:"name"`
}

func (p *Test) Bind(r *http.Request) error {
    err := json.NewDecoder(r.Body).Decode(p)
    if err != nil {
        return err
    }
    return nil
}

func main() {
    r := chi.NewRouter()

    r.Post("/products", func(w http.ResponseWriter, r *http.Request) {
        var p Test
        // err := render.Bind(r, &p)
        err := json.NewDecoder(r.Body).Decode(&p)

        if err != nil {
            panic(err)
        }

        fmt.Println(p)
    })

    http.ListenAndServe(":8080", r)
}

Когда я не пользуюсь render.Bind() (от "github.com/pressly/chi/render"), работает как положено.

Тем не менее, когда я раскомментирую строку err := render.Bind(r, &p) и я комментирую строку err := json.NewDecoder(r.Body).Decode(&p)паникует EOF:

2017/06/20 22:26:39 http: panic serving 127.0.0.1:39696: EOF

и, таким образом, json.Decode() выходит из строя.

Я делаю что-то не так или это http.Request.Body уже читал где-то еще раньше render.Bind() называется?

1 ответ

Решение

Цель render.Bind- выполнить декодирование и выполнить Bind(r) делать операции пост-декодирования.

Например:

type Test struct {
   Name string `json:"name"`
}

func (p *Test) Bind(r *http.Request) error {
   // At this point, Decode is already done by `chi`
   p.Name = p.Name + " after decode"
  return nil
}

Если вам нужно выполнить только JSON-декодирование, после декодирования не нужно выполнять никаких других действий в отношении декодированных значений. Просто используйте:

// Use Directly JSON decoder of std pkg
err := json.NewDecoder(r.Body).Decode(&p)

ИЛИ ЖЕ

// Use wrapper method from chi DecodeJSON
err := render.DecodeJSON(r.Body, &p)
Другие вопросы по тегам