I'm using Beego to develop a web server.
I used beego.Controller
to process the POST requests. In my case, the POST request contains a JSON:
{
"name": "titi",
"password": "123456"
}
Here is my code:
type TestController struct {
beego.Controller
}
type User struct {
Name string `json:"name"`
Password string `json:"password"`
}
func (c *TestController) Post() {
var ob md.User
var err error
if err = json.Unmarshal(c.Ctx.Input.RequestBody, &ob); err == nil {
logs.Debug(ob.Name)
logs.Debug(len(ob.Name))
} else {
logs.Error("illegal JSON")
}
}
This piece of code works fine. With the help of tags of the struct User
, "name"
is assigned to ob.Name
and "password"
is assigned to ob.Password
.
Now, I want to test some exception cases. For example, what if the JSON request doesn't contain the keys as expected:
{
"illegalKey1": "titi",
"illegalKey2": "123456"
}
As you see, I'm expecting "name"
and "password"
but now the keys become "illegalKey1"
and "illegalKey2"
. So I'm thinking this can cause some errors.
To my surprise, there isn't any error because err == nil
is still true, and len(ob.Name)
just becomes 0 now.
So is there some good method to process this case in Go/Beego?
I mean, I know that
if len(ob.Name) == 0 {
logs.Error("illegal JSON")
}
is OK but I'm wondering if there is some kind of more beautiful code? Otherwise, if there are 10 fields in the JSON, I have to do such an if
10 times. Obviously this is not good at all.
To make sure that JSON does not contain unexpected fields you can use Decoder
from "encoding/json"
package and it's method DisallowUnknownFields. See example here https://play.golang.org/p/bif833qxytE
Note that to json.NewDecoder
takes io.Reader
as an input. You can create io.Reader
from []byte
by using bytes.NewReader
Another topic is making sure that JSON contains all fields that are expected (OR these fields are in certain format). The answer to how make it work with "encoding/json"
package is to implement custom UnmarshalJSON
for the struct, can be found here. But I would not suggest using this approach for such task, because basically this is a validation of an input and I would rather use validation packages for this not to mix responsibilities. The most common one is go-playground/validator.v9 where you should look for required
tag. Validation cases are discussed here.