# Simplify JSON while deserializing into struct with StructTypes.jl

**URL:** <https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484>\
**Category:** Data\
**Tags:** data, json3, structtypes\
**Created:** [July 29, 2021, 9:07am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484 "2021-07-29T09:07:47Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jakob](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@Jakob](https://discourse.julialang.org/u/Jakob)\
**Post date:** [July 29, 2021, 9:07am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/1 "2021-07-29T09:07:47Z")

</div>

Hi everyone,

I have a relatively complex and nested JSON object (representing a patent application) which I would like to deserialize into a struct.  
However, I would like to “de-nest” the structure somewhat and between the different options provided by the awesome [StructTypes.jl](https://github.com/JuliaData/StructTypes.jl), such as wrapper types or mapping field names, I am still unsure what a feasible solution looks like.

Here’s a simplified example of what the JSON look like:

```json
    {
        "biblio": {
            "parties": {
                "applicants": [
                    {
                        "extracted_name": {
                            "value": "REAVELEY LAWRENCE D"
                        }
                    },
                    {
                        "extracted_name": {
                            "value": "BRYANT MARK"
                        }
                    }
                ],
                "inventors": [
                    {
                        "extracted_name": {
                            "value": "REAVELEY LAWRENCE D"
                        }
                    },
                    {
                        "extracted_name": {
                            "value": "BRYANT MARK"
                        }
                    }
                ]
            }
        }
    }

```

And this would be the corresponding target struct:

```julia
mutable struct Test
    applicants::Vector{String}
    inventors::Vector{String}
    Test() = new()
end

StructTypes.StructType(::Type{Test}) = StructTypes.Mutable()

```

Does anyone have an idea how to best approach this?

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [July 29, 2021, 9:21am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/2 "2021-07-29T09:21:15Z")

</div>

Firstly, it’s not clear to me why your struct is mutable and what the point of the internal constructor is. We can simplify to

```julia
struct Test
    applicants::Vector{String}
    inventors::Vector{String}
end

```

The naive approach would be an external constructor

```julia
get_names(dat) = map(x -> x["extracted_name"]["value"], dat)

Test(parties) = Test(get_names(parties["applicants"]), get_names(parties["inventors"]))

```

---

<div class="post-metadata">

**Author:** ![Jakob](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@Jakob](https://discourse.julialang.org/u/Jakob)\
**Post date:** [July 29, 2021, 9:35am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/3 "2021-07-29T09:35:05Z")

</div>

Thanks for the quick reply. As I understand it, the mutable struct and the inner constructor is StructTypes.jl’s way of rubustly dealing with e.g. missing fields in the JSON (see the [docs](https://juliadata.github.io/StructTypes.jl/stable/#DataTypes)).  
I guess doing the parsing and dealing with exceptions manually would be a possibility, but I would rather use the StructTypes machinery as the actual json is much more complex and the manual route would probably be more error prone and less efficient.

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [July 29, 2021, 9:39am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/4 "2021-07-29T09:39:01Z")

</div>

I see. Sorry, I’m not experienced with StructTypes.jl. I wonder though if that doesnt cause a lot of problems because you’re splitting up parsing and validation…

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [July 29, 2021, 10:07am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/5 "2021-07-29T10:07:42Z")

</div>

I do not think it is possible now, at least there was no replies in this issue: [https://github.com/JuliaData/StructTypes.jl/issues/10](https://github.com/JuliaData/StructTypes.jl/issues/10)

On the other hand, I doubt that it would be easy to work with vector types anyway.

So, probably the only way you have now is to define all intermediate structures and then flatten them by hand.

---

<div class="post-metadata">

**Author:** ![Jakob](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@Jakob](https://discourse.julialang.org/u/Jakob)\
**Post date:** [July 29, 2021, 11:19am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/6 "2021-07-29T11:19:34Z")

</div>

I see, thanks. Creating all the intermediate structs was my first approach and `JSON3.@generatetypes` actually turned that from a very tedious task into a breeze. But parsing directly into the final structure would have been more elegant.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [July 29, 2021, 11:33am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/7 "2021-07-29T11:33:00Z")

</div>

> [@Jakob](#):
>
> “de-nest” the structure somewhat

[GitHub - JuliaData/Strapping.jl: Tools for mapping between Julia structs and 2D tabular data.](https://github.com/JuliaData/Strapping.jl) might be useful; I’ve tried it a couple times and ran into some issues which I think have been fixed now.

---

<div class="post-metadata">

**Author:** ![Jakob](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@Jakob](https://discourse.julialang.org/u/Jakob)\
**Post date:** [July 29, 2021, 12:30pm UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/8 "2021-07-29T12:30:33Z")

</div>

Strapping.jl looks nice but in this case neither the input JSON nor the targeted output struct are really flat/tabular - it’s just that the JSON is more nested than necessary for the target struct so I would like to skip some of the nesting levels while keeping others.

---

<div class="post-metadata">

**Author:** ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)\
**Post date:** [August 3, 2021, 5:23am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/9 "2021-08-03T05:23:32Z")

</div>

Yeah, Strapping.jl works well when you need to completely unnest, but it’s certainly tricky when you only want to selectively unnest. I dealt with this once in a project, but not quite as complex as your case; in my case, I just did `JSON3.read(json)`, which returns a `JSON3.Object`. In StructTypes, we have a `StructTypes.constructfrom(T, x)` method that allows constructing `T` from `x`, where `x` is some kind of `AbstractDict` (like `JSON3.Object`).

Then you just define your own constructing machinery that does something like:

```julia
function unnest(json)
    x = JSON3.read(json)
    # pull the pieces out of x that are needed
end

```

---

<div class="post-metadata">

**Author:** ![Jakob](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@Jakob](https://discourse.julialang.org/u/Jakob)\
**Post date:** [August 3, 2021, 6:58am UTC](https://discourse.julialang.org/t/simplify-json-while-deserializing-into-struct-with-structtypes-jl/65484/10 "2021-08-03T06:58:29Z")

</div>

Thanks, I’ll give that a try.
