Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read request body two times in Golang [duplicate]

Tags:

json

request

go

type ValidationModel struct {
    Name     string `json:"name" valid:"alpha,required~Name is required"`
    Email    string `json:"email" valid:"email~Enter a valid email.,required~Email is required."`
    Password string `json:"password" valid:"required~Password is required"`
}

validationModel := ValidationModel{}

json.NewDecoder(r.Body).Decode(&validationModel)

_, err := govalidator.ValidateStruct(validationModel)

First I am validating the request body using govalidator.

type UserModel struct {
    ID           bson.ObjectId `json:"_id" bson:"_id"`
    Name         string        `json:"name" bson:"name"`
    Email        string        `json:"email" bson:"email"`
    Password     string        `json:"password,omitempty" bson:"-"`
    PasswordHash string        `json:"-" bson:"passwordHash"`
    Salt         string        `json:"-" bson:"salt"`
    Token        string        `json:"token,omitempty" bson:"-"`
}


user := models.UserModel{}
json.NewDecoder(r.Body).Decode(&user)

fmt.Println(user)

And after validating the request, again I am decoding the request body into user struct, but the request body has been read once using validationModel, so when I try to again decode it into user, it is not giving me any values.

I can think of two solutions here:

  1. Store request body in one separate variable, and use that variable two times.

  2. Copy validationModel values in user.

But I don't have any idea about to implement these approaches and which approach is best to follow. Or is there any other solution which can be implemented?

Thanks in advance.

like image 984
sohamdodia Avatar asked Nov 18 '18 08:11

sohamdodia


1 Answers

Storing the data can be easily done with ioutil.ReadAll():

data, err := ioutil.ReadAll(r.Body)

If you need the data back as a io.Reader (which is how the r.Body is), then you can use bytes.NewReader():

reader := bytes.NewReader(data)

And ACTUALLY, r.Body is a io.ReadCloser, so if you need that you can use ioutil.NopCloser() in conjunction with bytes.NewReader():

reader := ioutil.NopCloser(bytes.NewReader(data))
like image 60
poy Avatar answered Oct 14 '22 05:10

poy