What You'll Learn
- How to approach a large, nested JSON response without getting lost
- A repeatable process for finding the fields you need
- How to use JSONPath-style thinking to navigate complex structures
- How to handle arrays of mixed-shape objects
Why This Matters
Real API responses are messy. A single call to GitHub's API can return 50+ fields nested three levels deep, and you only need 4 of them. Beginners try to read the whole thing at once and get overwhelmed. This lesson gives you a process that works for any response.
The 4-Step Process for Reading Any JSON
- Pretty-print it. Indentation reveals structure.
- Identify the root type. Is it an object or an array?
- Map the top-level keys. Don't go deep yet — just list what's at the top.
- Drill down only into the keys you care about. Ignore the rest.
Worked Example — A GitHub Repository Response
The GitHub API endpoint GET /repos/{owner}/{repo} returns information about a repository. Let's fetch data for the Facebook React repo:
curl https://api.github.com/repos/facebook/react
The response (truncated for readability — the real response has 80+ fields):
{
"id": 10270250,
"name": "react",
"full_name": "facebook/react",
"owner": {
"login": "facebook",
"id": 69631,
"type": "Organization",
"avatar_url": "https://avatars.githubusercontent.com/u/69631?v=4"
},
"private": false,
"html_url": "https://github.com/facebook/react",
"description": "The library for web and native user interfaces.",
"fork": false,
"created_at": "2013-05-24T16:15:54Z",
"updated_at": "2026-08-22T14:32:11Z",
"pushed_at": "2026-08-23T07:22:18Z",
"homepage": "https://react.dev",
"size": 293820,
"stargazers_count": 231540,
"watchers_count": 231540,
"language": "JavaScript",
"license": {
"key": "mit",
"name": "MIT License",
"url": "https://api.github.com/licenses/mit"
},
"default_branch": "main",
"topics": ["react", "javascript", "library", "frontend"]
}
Step 1 — Pretty-Print It
Raw JSON from APIs often comes back as a single line. Always pretty-print it first. In your terminal:
curl https://api.github.com/repos/facebook/react | python -m json.tool
Or use the jq tool:
curl https://api.github.com/repos/facebook/react | jq .
Indentation makes the structure visible at a glance.
Step 2 — Identify the Root Type
The response starts with {, so it's an object. If it started with [, it would be an array.
Step 3 — Map the Top-Level Keys
Just read the top-level keys, ignoring values for now:
id, name, full_name, owner, private, html_url, description,
fork, created_at, updated_at, pushed_at, homepage, size,
stargazers_count, watchers_count, language, license,
default_branch, topics
You now know what's available without reading every value.
Step 4 — Drill Into Only What You Need
Suppose you need to answer: "Who owns this repo, what license is it under, and how many stars does it have?"
Owner
The owner key holds an object. Drill in:
data.owner.login // "facebook"
data.owner.type // "Organization"
License
The license key holds an object (or null if no license):
data.license.name // "MIT License"
data.license.key // "mit"
Stars
The stargazers_count key holds a number directly:
data.stargazers_count // 231540
Putting it together in JavaScript
const response = await fetch("https://api.github.com/repos/facebook/react");
const data = await response.json();
console.log(`Owner: ${data.owner.login}`);
console.log(`License: ${data.license?.name ?? "None"}`);
console.log(`Stars: ${data.stargazers_count}`);
Output:
Owner: facebook
License: MIT License
Stars: 231540
Handling Arrays of Mixed-Shape Objects
Sometimes an array contains objects with different shapes. Example: an activity feed where each item has a type field that determines which other fields exist:
{
"feed": [
{"type": "commit", "sha": "abc123", "message": "fix bug"},
{"type": "issue", "number": 42, "title": "Bug report"},
{"type": "comment", "id": 99, "body": "Looks good"}
]
}
Process it with a type check:
data.feed.forEach(item => {
if (item.type === "commit") console.log(item.sha, item.message);
else if (item.type === "issue") console.log(item.number, item.title);
else if (item.type === "comment") console.log(item.id, item.body);
});
Common Mistakes
- Reading the entire response top to bottom. Inefficient. Map top-level keys first, then drill in.
- Forgetting that nested keys can be null. Always check
if (data.license)before readingdata.license.name. - Hard-coding array indices.
data.items[0]breaks if the array is empty. Loop or check length first. - Not pretty-printing. Compressed JSON is unreadable. Always format before debugging.
- Trusting field names to match across APIs. GitHub uses
login, Twitter usesusername, Slack usesname. Always check the specific API's docs.
Practical Exercise (15 minutes)
- Call
https://api.github.com/repos/microsoft/vscode(use cURL or browser). - Pretty-print the response.
- Map the top-level keys.
- Extract: owner login, primary language, license name, stars count, open issues count, default branch.
- Write JavaScript or Python code that fetches and prints these fields.
Mini Challenge
Call https://api.github.com/users/torvalds/repos. It returns an array of repositories. Write code that prints the name and star count of the top 5 repos by stars. Hint: sort by stargazers_count descending, take the first 5.
Key Takeaways
- Pretty-print first; structure becomes visible.
- Identify the root type (object or array), then map top-level keys.
- Drill into only the keys you need — ignore the rest.
- Always handle null and missing keys defensively.
- For arrays of mixed-shape objects, branch on a
typefield.
Previously: Lesson 12 covered JSON objects, arrays, and nesting.
Today: You practiced reading a real, complex API response.
Next: Lesson 14 shows common JSON mistakes and how to validate JSON.
FAQ
What is jq and should I learn it?
jq is a command-line JSON processor. It lets you extract and transform JSON with expressions like jq '.owner.login'. Very useful for quick terminal work. Install it and try a few queries — the basics take 15 minutes to learn.
Why does GitHub return so many fields I don't need?
APIs return everything a client might want because they don't know in advance which fields you need. Some APIs support "sparse fieldsets" — you specify which fields to return (e.g., ?fields=name,owner.login). GraphQL was invented partly to solve this problem.
Comments
Comments
Post a Comment