Как разобрать JSON из двойного вложенного ответа - PullRequest
0 голосов
/ 09 мая 2019

Если я получаю ответ JSON для конечной точки cars:

{
  data: {
    cars: [
      { make: "Tesla", model: "S" }
    ]
  }
}

А у меня есть класс Car:

class Car
  JSON.mapping(
    make: String,
    model: String
  )
end

Как я могу разобрать ответ, чтобы корень спустился на два уровня? Я знаю, что могу сделать Car.from_json(json_string, "data"), но не могу найти способ указать другой корневой ключ.

Если нет способа сделать это, что будет самым простым способом без создания другого класса только для уровня cars?

1 Ответ

4 голосов
/ 09 мая 2019

Есть несколько подходов, которые вы можете использовать здесь.

Один простой, хотя и наименее эффективный, - просто дважды проанализировать:

cars = Array(Car).from_json(JSON.parse(json)["data"]["cars"].to_json)

https://carc.in/#/r/6vnk

Тогда, как вы упомянули, вы можете просто создавать отображения для внешних классов. Нет более быстрого способа по сравнению с тем, что у вас есть:

class Root
  JSON.mapping(data: Data)
end

class Data
  JSON.mapping(cars: Array(Car))
end

class Car
  JSON.mapping(
    make: String,
    model: String
  )
end

cars = Root.from_json(json).data.cars

https://carc.in/#/r/6vnm

Или, если вы предпочитаете использовать JSON::Serializable API:

class Root
  include JSON::Serializable
  property data : Data
end

class Data
  include JSON::Serializable
  property cars : Array(Car)
end

class Car
  include JSON::Serializable
  property  make : String
  property  model : String
end

cars = Root.from_json(json).data.cars

https://carc.in/#/r/6vno

Наконец, последний подход заключается в непосредственном управлении JSON::PullParser API:

parser = JSON::PullParser.new(json)
cars = nil
parser.on_key("data") do
  parser.on_key("cars") do
    cars = Array(Car).new(parser)
  end
end

https://carc.in/#/r/6vni

...