json: недопустимое использование строкового тега структуры [закрыто]

Я пытаюсь написать простую лямбда-функцию Go AWS без сервера POST.

      package main

import (
    "fmt"
)

import (
    "encoding/json"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

// RequestBodyType is our self-made struct to process JSON request from Client
type RequestBodyType struct {
    Event       string `string:"event,string,omitempty"`
    EventParams EventParamsType
}

// ResponseBodyType is our self-made struct to build response for Client
type ResponseBodyType struct {
    Event       string `string:"event,string,omitempty"`
    EventParams EventParamsType
}

// Probably problematic struct?
type EventParamsType struct {
    Name string `json:"name,string,omitempty"`
    Age  int64  `json:"age,omitempty"`
}

// Handler function Using AWS Lambda Proxy Request
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

    // RequestBody will be used to take the json response from client and build it
    requestBody := RequestBodyType{
        Event: "",
        EventParams: EventParamsType{
            Name: "",
            Age:  0,
        },
    }

    // Unmarshal the json, return 404 if error
    err := json.Unmarshal([]byte(request.Body), &requestBody)
    if err != nil {
        return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
    }

    // We will build the BodyResponse and send it back in json form
    responseBody := &ResponseBodyType{
        Event:       requestBody.Event,
        EventParams: EventParamsType{
            Name: requestBody.EventParams.Name,
            Age: requestBody.EventParams.Age,   
        },
    }

    fmt.Println("RESPONSE BODY")
    fmt.Println(responseBody)

    // Marshal the response into json bytes, if error return 404
    response, err := json.Marshal(&responseBody)
    if err != nil {
        return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
    }

    //Returning response with AWS Lambda Proxy Response
    return events.APIGatewayProxyResponse{Body: string(response), StatusCode: 200}, nil
}

func main() {
    lambda.Start(Handler)
}

Все работает нормально, если я делаю запрос curl с одним ключом объекта JSON, например:

      curl -X POST https://my.url/dev/event  -d '{"event": "test"}'

И я получаю ответ

      {"Event":"test","EventParams":{}

Но если я сделаю запрос с вложенным json-объектом, например:

      curl -X POST https://my.url/dev/event  -d '{"event": "test","eventParams": {"name": "peter","age": 13}}'

Тогда я получаю ответ

      json: invalid use of ,string struct tag, trying to unmarshal "peter" into string

Я считаю, что, вероятно, неправильно спроектировал EventParamsType? Или я неправильно строю ResponseBodyType?

1 ответ

Решение

Как говорится в ошибке, ваше использование недопустимо для ввода JSON. Убери это:

          Name string `json:"name,omitempty"`

,string может быть действительным в теге JSON и указывает на то, что номер должен быть маршалирован как строковый литерал. В случае значения, которое уже является строкой, это означает, что оно ожидает строку в кавычках JSON (которой, по-видимому, не является ваш ввод).

Это объясняется в документации :

Параметр «строка» указывает на то, что поле хранится как JSON внутри строки в кодировке JSON. Он применяется только к полям строкового, с плавающей запятой, целочисленным или логическим типам. Этот дополнительный уровень кодирования иногда используется при взаимодействии с программами JavaScript:

       Int64String int64 `json:",string"`

Подробности смотрите на детской площадке .


Кроме того, как указал @Adrian, это бессмысленный тег (во всяком случае, для целей маршалинга JSON (un)). Ты наверное хочешь json: вместо (хотя некоторые библиотеки могут использовать тег с именем string:... 🤷

Другие вопросы по тегам