Kanishka
Kanishka

Reputation: 1137

Strange Request Body in Golang API

I have created an API server using golang and ravel. In one of the POST methods, I need to read the body and decode it to a model before saving it. But it is failing to do so. This is the guide I used https://medium.com/@kyawmyintthein/revel-mgo-restful-generator-for-revel-web-framework-mongodb-86209de3977e

The expected behaviour is to create the user object in the mongoDB. But I am getting an error response. Something is going wrong while Decoding it to user struct.

Controller method:

func (c UserController) Create() revel.Result {

    fmt.Print("Body: ")
    fmt.Println(c.Request.Body)
    var (
        user models.User
        err  error
    )

    err = json.NewDecoder(c.Request.Body).Decode(&user)
    if err != nil {
        errResp := buildErrResponse(err, "403")
        c.Response.Status = 403
        return c.RenderJSON(errResp)
    }

    user, err = models.AddUser(user)
    if err != nil {
        errResp := buildErrResponse(err, "500")
        c.Response.Status = 500
        return c.RenderJSON(errResp)
    }
    c.Response.Status = 201
    return c.RenderJSON(user)
}

User Model:

package models

import (
    "gopkg.in/mgo.v2/bson"
    "time"
    "userAPI/app/models/mongodb"
)

type User struct {
    ID        bson.ObjectId `json:"id" bson:"_id"`
    Name      string        `json:"name" bson:"name"`
    Email     string        `json:"email" bson:"email"`
    Phone     string        `json:"phone" bson:"phone"`
    Username  string        `json:"username" bson:"username"`
    CreatedAt time.Time     `json:"created_at" bson:"created_at"`
    UpdatedAt time.Time     `json:"updated_at" bson:"updated_at"`
}

JSON body used in POST request

{
    "name":"kanishka",
    "email":"[email protected]",
    "phone":"91238901238",
    "username":"k"
}

This is the response I am getting

{
    "error_code": "403",
    "error_message": "EOF"
}

The output of println(c.Request.Body) on top of the controller method shows

&{0xc4202ffa80 false true {0 0} true false false 0x12a1430}

This is my first attempt at golang. Kindly help me to proceed further.

Upvotes: 1

Views: 842

Answers (1)

putu
putu

Reputation: 6444

After searching, I found this issue #1011. Quote to the response:

Revel automatically calls ParseForm, ParseMultipartForm or whatever function is needed for a request, so req.Body is parsed and all valuable information is stored to controller.Params.(Fixed, Route, Query, Form, Files).

It means that, before calling your controller's method, the request body already being read by revel, so when you try to read it again the result will be EOF. From the docs, instead of using json.Decoder and request body, try the following:

c.Params.BindJSON(&user)

Upvotes: 2

Related Questions