Java-Web:Using jq to process Json - Exercises

From Juneday education
Jump to: navigation, search

We will soon add exercises on jq here. In the meanwhile, please copy all steps on the previous page and verify that you can follow them in your own terminal.

Exercises work in progress

Get Json from Punk API

Here's an API we'll use for these exercises:

Read the documentation carefully, and then find the query to use in order to get a random beer (it's documented on the paged linked above).

Expand using link to the right to see the suggested solution.

https://api.punkapi.com/v2/beers/random

Now, use lwp-request -m GET or curl -s to fetch a random beer so that it is printed to standard out.

Expand using link to the right to see the suggested solution.

lwp-request -m GET https://api.punkapi.com/v2/beers/random
curl -s https://api.punkapi.com/v2/beers/random

Get a picture of the structure of all that Json

That's quite a lot of data, isn't it?

Let's pipe it through jq '.' to at least make it more readable. Do it!

Expand using link to the right to see the suggested solution.

This is what the random beer we got looked like:

$ curl -s https://api.punkapi.com/v2/beers/random | jq '.'
[
  {
    "id": 193,
    "name": "Blitz Berliner Weisse",
    "tagline": "Berliner Fruit Beer.",
    "first_brewed": "07/2013",
    "description": "Our sour recipe for all fruit Blitz beers uses a process called kettle souring. In this we steep a bag of malt in the wort to allow the bacteria to grow in it.",
    "image_url": "https://images.punkapi.com/v2/keg.png",
    "abv": 3,
    "ibu": 8,
    "target_fg": 1040,
    "target_og": 1007,
    "ebc": 9,
    "srm": 4.5,
    "ph": 3.2,
    "attenuation_level": 82.5,
    "volume": {
      "value": 20,
      "unit": "liters"
    },
    "boil_volume": {
      "value": 25,
      "unit": "liters"
    },
    "method": {
      "mash_temp": [
        {
          "temp": {
            "value": 65,
            "unit": "celsius"
          },
          "duration": 60
        }
      ],
      "fermentation": {
        "temp": {
          "value": 19,
          "unit": "celsius"
        }
      },
      "twist": "Before main fermentation steep a bag of malt in the wort for 48 hours. Re boil the wort before pitching in the yeast for the main fermentation."
    },
    "ingredients": {
      "malt": [
        {
          "name": "Extra Pale",
          "amount": {
            "value": 1.88,
            "unit": "kilograms"
          }
        },
        {
          "name": "Wheat",
          "amount": {
            "value": 1.88,
            "unit": "kilograms"
          }
        }
      ],
      "hops": [
        {
          "name": "Magnum",
          "amount": {
            "value": 8.5,
            "unit": "grams"
          },
          "add": "start",
          "attribute": "bitter"
        }
      ],
      "yeast": "Wyeast 1056 - American Ale™"
    },
    "food_pairing": [
      "Grilled salmon with a light lemon sauce",
      "Lobster bisque",
      "Cheesecake with raspberry (or peach/passion fruit) sauce"
    ],
    "brewers_tips": "Making sour beers is an art, and is mostly related to trial and error with your process. Experiment with different temperatures for steeping the grain. 40 - 50°C willallow the lacto to grow and produce a clean profile.",
    "contributed_by": "Ali Skinner <AliSkinner>"
  }
]

With such amount of data, it is hard to know how to parse it with jq.

Let's make jq give us a hint of the structure. We made a script for that!

The script tries to create paths to all elements in a Json, so that you get an overview of the Json structure.

We think the script is good enough™.


$ curl -s https://api.punkapi.com/v2/beers/random | ./jq-paths.sh

.[0]
.[0]."id"
.[0]."name"
.[0]."tagline"
.[0]."first_brewed"
.[0]."description"
.[0]."image_url"
.[0]."abv"
.[0]."ibu"
.[0]."target_fg"
.[0]."target_og"
.[0]."ebc"
.[0]."srm"
.[0]."ph"
.[0]."attenuation_level"
.[0]."volume"
.[0]."volume"."value"
.[0]."volume"."unit"
.[0]."boil_volume"
.[0]."boil_volume"."value"
.[0]."boil_volume"."unit"
.[0]."method"
.[0]."method"."mash_temp"
.[0]."method"."mash_temp"[0]
.[0]."method"."mash_temp"[0]."temp"
.[0]."method"."mash_temp"[0]."temp"."value"
.[0]."method"."mash_temp"[0]."temp"."unit"
.[0]."method"."mash_temp"[0]."duration"
.[0]."method"."fermentation"
.[0]."method"."fermentation"."temp"
.[0]."method"."fermentation"."temp"."value"
.[0]."method"."fermentation"."temp"."unit"
.[0]."method"."twist"
.[0]."ingredients"
.[0]."ingredients"."malt"
.[0]."ingredients"."malt"[0]
.[0]."ingredients"."malt"[0]."name"
.[0]."ingredients"."malt"[0]."amount"
.[0]."ingredients"."malt"[0]."amount"."value"
.[0]."ingredients"."malt"[0]."amount"."unit"
.[0]."ingredients"."malt"[1]
.[0]."ingredients"."malt"[1]."name"
.[0]."ingredients"."malt"[1]."amount"
.[0]."ingredients"."malt"[1]."amount"."value"
.[0]."ingredients"."malt"[1]."amount"."unit"
.[0]."ingredients"."malt"[2]
.[0]."ingredients"."malt"[2]."name"
.[0]."ingredients"."malt"[2]."amount"
.[0]."ingredients"."malt"[2]."amount"."value"
.[0]."ingredients"."malt"[2]."amount"."unit"
.[0]."ingredients"."malt"[3]
.[0]."ingredients"."malt"[3]."name"
.[0]."ingredients"."malt"[3]."amount"
.[0]."ingredients"."malt"[3]."amount"."value"
.[0]."ingredients"."malt"[3]."amount"."unit"
.[0]."ingredients"."hops"
.[0]."ingredients"."hops"[0]
.[0]."ingredients"."hops"[0]."name"
.[0]."ingredients"."hops"[0]."amount"
.[0]."ingredients"."hops"[0]."amount"."value"
.[0]."ingredients"."hops"[0]."amount"."unit"
.[0]."ingredients"."hops"[0]."add"
.[0]."ingredients"."hops"[0]."attribute"
.[0]."ingredients"."hops"[1]
.[0]."ingredients"."hops"[1]."name"
.[0]."ingredients"."hops"[1]."amount"
.[0]."ingredients"."hops"[1]."amount"."value"
.[0]."ingredients"."hops"[1]."amount"."unit"
.[0]."ingredients"."hops"[1]."add"
.[0]."ingredients"."hops"[1]."attribute"
.[0]."ingredients"."yeast"
.[0]."food_pairing"
.[0]."food_pairing"[0]
.[0]."food_pairing"[1]
.[0]."food_pairing"[2]
.[0]."brewers_tips"
.[0]."contributed_by"

Let's try it:

$ curl -s https://api.punkapi.com/v2/beers/random | jq '.[0]."ingredients"."hops"[0]."name"'
"Tomahawk"
$ curl -s https://api.punkapi.com/v2/beers/random | jq '.[0]."method"."mash_temp"[0]."duration"'
75

.[0]."ingredients"."hops" is an array, we can see. The full path to use to get all hops' names as an array will then be:

jq '[{hop_name:.[0]."ingredients"."hops"[]."name"}]'
$ curl -s https://api.punkapi.com/v2/beers/random | jq '[{"hop_name":.[0]."ingredients"."hops"[]."name"}]'
[
 {
  "hop_name": "Magnum"
 },
 {
  "hop_name": "Willamette"
 },
 {
  "hop_name": "First Gold"
 }
]

Now it's your turn

Use the outline from our script, to list all food pairings for some random beer. We want you to include the name of the beer, and an array called foods.

Expand using link to the right to see the suggested solution.

$ curl -s https://api.punkapi.com/v2/beers/random | jq '{name: .[0]."name", foods:.[0]."food_pairing"}'
{
  "name": "10 Heads High",
  "foods": [
    "Arrabiata pasta",
    "Mulled cheddar",
    "Toasted almond cake"
  ]
}

Links

Source code

Where to go next

The previous page was Java-Web:Using_jq_to_process_Json with the theory for these exercises.

The Next page is a new topic, Java-Web:Creating_JSON_from_Java

The TOC goes to Java_Web_programming.

« PreviousBook TOCNext »