Is there a Julia package allowing to access json objects like jqlang?

In REPL it’s convenient to use jqlang syntax like

curl 'https://<graphql-api>' -X POST \
  -H 'content-type: application/json' \
  --data """<graphql-query>""" | \
jq '.data.blocks[0].number

is there a way to do something similar in Julia?

It’s already very convenient to do something like:

using JSON3, Pipe
@pipe read("data.json") |> JSON3.read |>
  getindex(_, :data) |> getindex(_, :blocks) |> getindex(_, 1)

but I am looking for a more compact way to explore the json object, it’s a bit cumbersome to call getindex multiple times.

Not sure if it solves your problem, but you can call getindex implicitly via indexing, e.g. (following your example):

@pipe read("data.json") |> JSON3.read |> _[:data] |> _[:blocks] |> _[1]

or even:

@pipe "data.json" |> read |> JSON3.read |> _[:data][:blocks][1]

Also check out this presentation at JuliaCon 2023.

1 Like

You can try using PropertyDicts to simplify field access via properties:

julia> using JSON, PropertyDicts
julia> content = JSON.parsefile("/path/to/my.json"; dicttype = PropertyDict);
julia> content.data.blocks[1].number
2 Likes

If you like jq you can use it directly from jq_jll.jl:

julia> using JSON3, jq_jll

julia> jq(data, expr) = sprint(io -> run(pipeline(IOBuffer(data), `$(jq_jll.jq()) -c $expr`, io)))
jq (generic function with 1 method)

julia> jq("""{"x": [{"y": 1},{"y": 2}]}""", "[.x[].y]") |> JSON3.read
2-element JSON3.Array{Int64, Base.CodeUnits{UInt8, String}, Vector{UInt64}}:
 1
 2
3 Likes

I’ve been using JSON3 a lot without knowing the motivations behind it, thanks for the share :wink:

Im curious, what is the benefit of using the jll compared to shelling out to regular jq?

You are running it in a subprocess anyway no? Is it simply the ability to install independently from the system binaries?

It means you don’t need to rely on jq being installed already. And you can control which version you use, just like any other package.

1 Like