jsonapi golang как взять поределенные поля

Рейтинг: 0Ответов: 2Опубликовано: 22.06.2023

Есть ответ от сервиса:

{
   "data":{
      "type":"promocode",
      "id":"0188e28b-a7c2-7f5a-8e09-c6aabdc90667",
      "attributes":{
         "code":"NEW-YGTU-TXAP-O1UH",
         "expiredAt":"2023-06-25T03:00:00+03:00",
         "createdAt":"2023-06-21T06:03:31+03:00"
      },
      "relationships":{
         "promocodeDiscountAction":{
            "data":{
               "type":"percentDiscountAction",
               "id":"5"
            }
         }
      }
   },
   "included":[
      {
         "type":"percentDiscountAction",
         "id":"5",
         "attributes":{
            "category":"cart",
            "value":30
         }
      }
   ]
}

Предположим мне нужно взять поля по пути:

Data.Attributes.Code

relationships.promocodeDiscountAction.data.type

included.type

и смаршалить в стракт где будет три поля Code, DataType, IncludedType

Не могу понять как это сделать

Ответы

▲ 0

Лучше всего смоделировать структуру как есть, со всеми вложенностями, и потом брать значения из неё, или смэппить в плоскую структуру своим кодом.

Ещё можно прочитать как map, а оттуда уже вытащить - но вытаскивание потребует многих приведений типа.

    var x map[string]interface{}

    json.Unmarshal([]byte(jsonStr), &x)
    

Как вариант, можно создать свой type dict map[string]interface{}, добавить ему удобных методов и работать уже через него, см. https://stackoverflow.com/a/65380727/998126

▲ 0

Если сервер всегда отвечает именно теми полями, которые у вас в примере, то можно сгенерировать структуру Go и декодировать JSON в неё.

Мне обычно лень создавать структуры руками, поэтому я пользуюсь онлайновыми конверторами. Например, https://mholt.github.io/json-to-go/

В вашем случае этот конвертор сделал такую структуру:

type AutoGenerated struct {
    Data struct {
        Type       string `json:"type"`
        ID         string `json:"id"`
        Attributes struct {
            Code      string    `json:"code"`
            ExpiredAt time.Time `json:"expiredAt"`
            CreatedAt time.Time `json:"createdAt"`
        } `json:"attributes"`
        Relationships struct {
            PromocodeDiscountAction struct {
                Data struct {
                    Type string `json:"type"`
                    ID   string `json:"id"`
                } `json:"data"`
            } `json:"promocodeDiscountAction"`
        } `json:"relationships"`
    } `json:"data"`
    Included []struct {
        Type       string `json:"type"`
        ID         string `json:"id"`
        Attributes struct {
            Category string `json:"category"`
            Value    int    `json:"value"`
        } `json:"attributes"`
    } `json:"included"`
}

Тогда парсинг можно написать так:

    var response AutoGenerated
    err := json.Unmarshal([]byte(responseStr), &response)
    if err != nil {
        panic(err)
    }

Доступ к полям

    fmt.Println("Data.Attributes.Code:", response.Data.Attributes.Code)
    fmt.Println("relationships.promocodeDiscountAction.data.type:", response.Data.Relationships.PromocodeDiscountAction.Data.Type)
    fmt.Println("included.type:", response.Included[0].Type)

Полный пример https://go.dev/play/p/PhE9WSn2AL9

Data.Attributes.Code: NEW-YGTU-TXAP-O1UH
relationships.promocodeDiscountAction.data.type: percentDiscountAction
included.type: percentDiscountAction