6

I use go-chi as HTTP-router, and I want to reuse one method inside another

func Registration(w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body) // if you delete this line, the user will be created   
    // ...other code

    // if all good then create new user
    user.Create(w, r)
}

...

func Create(w http.ResponseWriter, r *http.Request) {
  b, err := ioutil.ReadAll(r.Body)  
  // ...other code

  // ... there I get the problem with parse JSON from &b
}

user.Create return error "unexpected end of JSON input"

Actually, after I executed ioutil.ReadAll
user.Create ceased to parse JSON,
in r.Body there was an empty array[]how can I fix this problem?

kostix
  • 51,517
  • 14
  • 93
  • 176
batazor
  • 852
  • 2
  • 16
  • 36

2 Answers2

9

The outer handler reads the request body to EOF. When the inner handler is called, there's nothing more to read from the body.

To fix the issue, restore the request body with the data read previously in the outer handler:

func Registration(w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body) 
    // ...other code
    r.Body = ioutil.NopCloser(bytes.NewReader(b))
    user.Create(w, r)
}

The function bytes.NewReader() returns a io.Reader on a byte slice. The function ioutil.NopCloser converts an io.Reader to the io.ReadCloser required for r.Body.

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
3

In the end, I was able to recover data in this way:

r.Body = ioutil.NopCloser(bytes.NewBuffer(b))
batazor
  • 852
  • 2
  • 16
  • 36