Well, for one—and I do this a lot—you can quickly and easily get JSON data into a readable form. Let’s take a look at the Chuck Norris API [2], [3] which gives us a random joke. But as Listing 1 shows, it is unfortunately unformatted.
Listing 1: Calling and formatting the Chuck Norris API curl https://api.chucknorris.io/jokes/random {"categories":[],"created_at":"2020-01-05 13:42:29.569033","icon_url":"https://assets.chucknorris.host/img/avatar/chuck-norris.png","id":"NQXb8Y1YTD-GvG1YScZdAA","updated_at":"2020-01-05 13:42:29.569033","url":"https://api.chucknorris.io/jokes/NQXb8Y1YTD-GvG1YScZdAA","value":"Don't ever make the mistake of staring at Chuck Norris or you will find yourself picking up your teeth with two broken arms and counting them with two black eyes."}%
However, if we pipe the output through jq (`curl https://api.chucknorris.io/jokes/random | jq `), right away, the image looks much nicer (Listing 2).
Listing 2: Formatted Joke curl https://api.chucknorris.io/jokes/random | jq "{value: .value, from: .updated_at}" { "value": "The sun moves across the sky because its running from Chuck Norris.", "from": "2020-01-05 13:42:29.569033" }
It doesn’t stop there. jq provides a query language based on JSONPath that includes operators for calculations, functions, variables, control structures, and much more. In Listing 2, I’ve already shown how individual elements can be selected and new objects are structured.
Basically, jq is based on filters. In the above example, the Object Identifier Index .value is a filter, as is .updated_at. They are available for array indexes, slices, and much more. In the example, I used curly brackets as a construction for objects, with a filter created by joining two individual filters with a comma.
The Open-Meteo API [4] provides weather forecasts. The Forecast API’s response looks something like what’s presented in Listing 3.
STAY TUNED!
Learn more about API Conference
Listing 3: Open-Meteo Weather Forecast API { "latitude": 52.52, "longitude": 13.419, "elevation": 44.812, "generationtime_ms": 2.2119, "utc_offset_seconds": 0, "hourly": { "time": ["2021-08-28T00:00", "2021-08-28T01:00", "2021-08-28T02:00", ...], "temperature_2m": [13, 12.7, 12.7, 12.5, 12.5, 12.8, 13, 12.9, 13.3, ...] }, "hourly_units": { "temperature_2m": "°C" }, "current_weather": { "time": "2021-08-28T09:00", "temperature": 13.3, "weathercode": 3, "windspeed": 10.3, "winddirection": 262 } }
If I want to know the average hourly temperature for the next seven days, using the operation shown in Listing 4 is very easy.
Listing 4: Value aggregation curl https://api.open-meteo.com/v1/forecast\?latitude\=50.75\&longitude\=6.18\&hourly\=temperature_2m\¤t_weather\=true |\ jq ".hourly.temperature_2m | add/length"
At the time of writing this, the average is 11.16 degrees Celsius. Time to unpack our warm cycling gear—or continue playing with jq’s filters and operators.
Links & Literature
[1] https://stedolan.github.io/jq/
[2] https://api.chucknorris.io