json Шаблоны проверки тела HTTP-запроса - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь понять шаблоны для проверки JSON тела.

Например,

  // I have this struct
  type Program struct {
    ProgramKey string `json:"program_key" validate:"required"`
    Active     *bool     `json:"active" validate:"required"`
  }

  // json request body
  {
    "program_key" : "example-key",
    "active" : false
  }

Я хочу запустить проверку моего запроса до того, как ошибка декодирования JSON исчезнет. Но не уверен, что это лучший способ сделать это.

Потому что всякий раз, когда я делаю декодирование,

   // json request body
   {
    "program_key" : "example-key",
    "active" : "false" // notice the string value here
   }
   json.NewDecoder(r.Body).Decode(&program);

Декодирование завершается неудачно, если потребитель отправляет строку false. Поскольку декодер JSON не может декодировать и назначить запрос. Я не против использовать это в качестве первого уровня обработки ошибок / проверки. Но, учитывая, я могу настроить сообщение об ошибке. Я не хочу раскрывать основные детали API для потребителя.

Я не могу найти хорошие узоры вокруг этой области.

1 Ответ

1 голос
/ 03 апреля 2020

Даже если есть ошибка от json.Decode, в зависимости от ошибки, структура, в которую вы анализируете результаты, может все же содержать некоторые результаты. Из документов Go, если вы попытаетесь проанализировать строку JSON с неправильным типом json.Decode, будет возвращена ошибка типа UnmarshalTypeError. Что-то вроде:

package main

import (
    "encoding/json"
    "fmt"
)

type Program struct {
    ProgramKey string `json:"program_key"`
    Active     bool   `json:"active"`
}

func (p *Program) String() string {
    return fmt.Sprintf("&Program{ProgramKey: %s, Active: %t", p.ProgramKey, p.Active)
}

func ParseProgram(jsonStr string) (*Program, error) {
    var p *Program
    err := json.Unmarshal([]byte(jsonStr), &p)
    if err != nil {
        switch err.(type) {
        case *json.UnmarshalTypeError:
            // Maybe log this or build a debug message from it.
            fmt.Println(err)
        default:
            return p, err
        }
    }
    // Inspect P further since it might still contain valid info.
    // ...
    return p, nil
}

func main() {
    jsonStr := `
        {
            "program_key": "example-key",
            "active": "false"
        }
    `
    p, err := ParseProgram(jsonStr)
    if err != nil {
        panic(err)
    }

    fmt.Println(p)
}

Производит:

json: cannot unmarshal string into Go struct field Program.active of type bool
&Program{ProgramKey: example-key, Active: false

Обратите внимание, что в p в main все еще заполнено поле ProgramKey.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...