Подтвердить что ты не робот

Unmarshaling json in Golang: обязательное поле?

Можно ли генерировать ошибку, если поле не было найдено в json, пока не было маршалинга в Голанге? Я не мог найти его в документации. Есть ли какой-либо тег, который задает поле по мере необходимости?

4b9b3361

Ответ 1

В пакете encoding/json нет тега, который устанавливает поле "required". Вам придется либо написать собственный метод MarshalJSON(), либо выполнить проверку почты для отсутствующих полей.

Чтобы проверить недостающие поля, вам нужно будет использовать указатели, чтобы различать отсутствующие/нулевые и нулевые значения:

type JsonStruct struct {
    String *string
    Number *float64
}

Полный рабочий пример:

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)
}

Игровая площадка

Ответ 2

Вы также можете переопределить unmarshalling для определенного типа (так что требуемое поле, захороненное в нескольких слоях json), без необходимости указывать в поле указатель.

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                                                                                                        
}