Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unmarshaling json in Go: required field?

Tags:

json

go

Is it possible to generate an error if a field was not found while parsing a JSON input using Go?

I could not find it in documentation.

Is there any tag that specifies the field as required?

like image 581
Alexander Ponomarev Avatar asked Oct 28 '13 11:10

Alexander Ponomarev


2 Answers

There is no tag in the encoding/json package that sets a field to "required". You will either have to write your own MarshalJSON() method, or do a post check for missing fields.

To check for missing fields, you will have to use pointers in order to distinguish between missing/null and zero values:

type JsonStruct struct {     String *string     Number *float64 } 

Full working example:

package main  import (     "fmt"     "encoding/json" )  type JsonStruct struct {     String *string     Number *float64 }  var rawJson = []byte(`{     "string":"We do not provide a number" }`)   func main() {     var s *JsonStruct     err := json.Unmarshal(rawJson, &s)     if err != nil {         panic(err)     }      if s.String == nil {         panic("String is missing or null!")     }      if s.Number == nil {         panic("Number is missing or null!")     }      fmt.Printf("String: %s  Number: %f\n", *s.String, *s.Number) } 

Playground

like image 113
ANisus Avatar answered Oct 16 '22 09:10

ANisus


You can also override the unmarshalling for a specific type (so a required field buried in a few json layers) without having to make the field a pointer. UnmarshalJSON is defined by the Unmarshaler interface.

type EnumItem struct {                                                                                                 Named                                                                                                              Value string                                                                                                   }                                                                                                                   func (item *EnumItem) UnmarshalJSON(data []byte) (err error) {                                                         required := struct {                                                                                                   Value *string `json:"value"`                                                                                   }{}                                                                                                                all := struct {                                                                                                        Named                                                                                                              Value string `json:"value"`                                                                                    }{}                                                                                                                err = json.Unmarshal(data, &required)                                                                              if err != nil {                                                                                                        return                                                                                                         } else if required.Value == nil {                                                                                      err = fmt.Errorf("Required field for EnumItem missing")                                                        } else {                                                                                                               err = json.Unmarshal(data, &all)                                                                                   item.Named = all.Named                                                                                             item.Value = all.Value                                                                                         }                                                                                                                  return                                                                                                         }                                                        
like image 45
Ian Walters Avatar answered Oct 16 '22 08:10

Ian Walters