HOWTO: JSON3 read json path value as Custom type or Convert JSON3.Object as Custom type

begin
  struct Book
    name
    price
    tags
  end

  StructTypes.StructType(::Type{Book}) = StructTypes.Struct()

  request_body_io = IOBuffer()
  response_body_io = IOBuffer()

  JSON3.write(request_body_io, Book("the julia", 11.11, ["programming", "julia"]))
  request_body_io |> seekstart

  response = request(
    "https://httpbin.org/post",
    method="POST",
    headers=Dict("accept" => "application/json", "content-type" => "application/json"),
    verbose=false,
    input=request_body_io,
    output=response_body_io,
  )

  @show response.status
  @show response.message

  body = response_body_io |> seekstart |> JSON3.read
  # => how to convert the JSON3.Object as type Book or how to read json path (e.g. root.json) and convert it's value as Type Book directly
  #
  @show body["json"]

end

UPDATE (provided by @Jeff_Emanuel )

  book = response_body_io |> seekstart |> JSON3.read |> x -> StructTypes.constructfrom(Book, x["json"])
  @show typeof(book) # => typeof(book) = Book
  @show book # => book = Book("the julia", 11.11, ["programming", "julia"])

https://quinnj.github.io/JSON3.jl/stable/#Read-JSON-into-a-type

I’ve looked at this but couldn’t find what I was looking for, or I didn’t know how to apply it to my needs

Use the 2-arg JSON3.read which takes a type instead of the single argument JSON3.read you have at the end of your code. Something like

body = JSON3.read( response_body_io |> seekstart, Book )

You might need to read the body into a String first.

I don’t want to convert the entire response body to type Book, but to convert its json field (root.json) to type Book

If you don’t have a type for the entire JSON structure, it may be simplest (if not fastest) to re-encode just the part that constitutes a book and the re-decode that as a Book. I’d look at defining a type for the entire structure.

could JSON3 Intermediate Type(e.g. JSON3.Object) convert as custom type ?

I’m not aware of any way to do that automatically. I haven’t used this, but you could experiment with Home · StructTypes.jl

1 Like

It works fine, thanks!

I don’t know if this takes advantage of the lazy parse feature of JSON3.