When Less Information is Better: using jq with the MAAS API

Sometimes, when working with a JSON API that returns a large amount of data, you want to focus on only the necessary information.

For example, the MAAS API returns large amounts of JSON data, and often you only want to see a subset of the output. If it were tabular ouput, you might use grep and awk. If it were an XML document, you might use an XPATH expression. But what about JSON data?

The jq tool comes in handy for this. (Use sudo apt-get install jq if you don't already have it installed.)

Here's an example of getting just the hostname, system_id, and status from the MAAS nodes API, printed one record per line.

$ maas root nodes read | jq '.[] | {hostname:.hostname, system_id: .system_id, status:.status}' --compact-output
{"hostname":"pxe-bond1","system_id":"4y3h7p","status":0}
{"hostname":"pxe-bond2","system_id":"4y3h7q","status":0}
{"hostname":"pxe1","system_id":"4y3h7r","status":6}
{"hostname":"pxe2","system_id":"4y3h7s","status":0}
{"hostname":"maas","system_id":"4y3h7n","status":null}

Similarly, if you want to print a JSON object that could be consumed by another program, you could slightly alter the jq filter string:

$ maas root nodes read | jq '[.[] | {hostname:.hostname, system_id: .system_id, status:.status}]'
[
  {
    "hostname": "pxe-bond1",
    "system_id": "4y3h7p",
    "status": 0
  },
  {
    "hostname": "pxe-bond2",
    "system_id": "4y3h7q",
    "status": 0
  },
  {
    "hostname": "pxe1",
    "system_id": "4y3h7r",
    "status": 6
  },
  {
    "hostname": "pxe2",
    "system_id": "4y3h7s",
    "status": 0
  },
  {
    "hostname": "maas",
    "system_id": "4y3h7n",
    "status": null
  }
]

I hadn't heard of jq before I saw another MAAS developer using it, but now that I've learned my way around it a little, it would be difficult to give up!