Challenge Easy

Call an HTTP API with curl: Processing JSON Responses with jq

Practice one of the most common command-line combinations for HTTP API access: fetch a JSON response with curl and pipe it into jq to pretty print, reshape, or get only the relevant parts.

HTTP APIs usually respond with JSON, and jq is the command-line tool for reading JSON. Piping curl into jq lets you pull one field out of a response, list an array, filter it, or compute something from it, in a one-off command or in a script.

In this challenge, you will practice such curl and jq pipelines on workstation-01 against the internal Artifact Inventory API at http://api.corp.internal:8080. The endpoints you need:

  • GET /api/v1/status - get service health, version, and build information
  • GET /api/v1/artifacts - list all artifacts known to the service
  • GET /api/v1/artifacts/<name>/manifest - read the manifest of an artifact

Task 1: Pull Out a Nested Field

The status endpoint reports which commit the service was built from, inside its build object. Which commit is it?

Hint 1

The jq command reads JSON from stdin when no file is given, so the output of curl can be piped into it. The filter . prints the whole document nicely formatted, which is a good first step for any endpoint:

curl -s http://api.corp.internal:8080/api/v1/status | jq .

The -s option keeps the progress meter of curl out of the output.

Hint 2

The filter .foo prints the value of the foo key, and keys of nested objects are chained with dots. The -r option prints the value as a raw string, without the JSON quotes:

echo '{"foo":{"bar":"hello"}}' | jq -r '.foo.bar'
hello

Task 2: List an Array One Element per Line

Write the names of all artifacts known to the service to ~/artifacts.txt, one bare name per line, without quotes, commas, or brackets.

Hint 3

The [] suffix iterates over an array, so .foo[] prints each element of foo as a separate output, and .foo[].bar prints one field of each. Without -r, the strings come out with quotes around them:

echo '{"foo":[{"bar":"apple"},{"bar":"banana"}]}' | jq -r '.foo[].bar'
apple
banana

Task 3: Filter Objects by an Attribute

Some artifacts are built for linux/arm64 and some for linux/amd64. Write the names of the linux/arm64 artifacts to ~/arm64.txt, one per line.

Hint 4

The select(<condition>) function keeps only the inputs for which the condition is true. String comparison uses ==, and a | .bar at the end picks the field to print:

echo '{"foo":[{"bar":"apple","color":"red"},{"bar":"banana","color":"yellow"}]}' | jq -r '.foo[] | select(.color == "yellow") | .bar'
banana

Task 4: Compute a Value

How many bytes do all artifacts take together? Add up the sizeBytes field of every artifact.

Hint 5

Square brackets around a filter collect its outputs into an array, and the add function sums an array of numbers:

echo '{"foo":[{"bar":10},{"bar":20},{"bar":5}]}' | jq '[.foo[].bar] | add'
35

Task 5: Collect Several Values at Once

The manifest of report-builder references one config object and several layers, each by digest. Write the config digest and every layer digest to ~/digests.txt, one per line. Remember that the manifest endpoint returns JSON only when asked for it with the Accept: application/vnd.corp.manifest.v2+json header.

Hint 6

A comma separates several filters, and jq prints the results of all of them in order. The comma works with iteration as well:

echo '{"foo":{"bar":"apple"},"baz":[{"bar":"banana"},{"bar":"cherry"}]}' | jq -r '.foo.bar, .baz[].bar'
apple
banana
cherry