Call an HTTP API with curl: Processing JSON Responses with jq
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 informationGET /api/v1/artifacts- list all artifacts known to the serviceGET /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