10 Common JSON Mistakes Developers Make and How to Fix Them
This article outlines ten frequent JSON pitfalls—from deeply nested structures and string literals to missing timezone data and lack of versioning—provides clear before‑and‑after code examples, and offers practical guidelines to write cleaner, safer, and more maintainable JSON for APIs and configuration files.
1. Avoid Deeply Nested Structures
Over‑nested objects make accessing values painful and error‑prone. Example of a painful nesting:
const userConfig = {
user: {
profile: {
personal: {
details: {
name: { first: "John", last: "Doe" }
}
}
}
}
};
const firstName = userConfig.user.profile.personal.details.name.first;Flatten the structure when possible:
const userConfig = {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
preferences: { theme: "dark", notifications: true }
};
const firstName = userConfig.firstName;Only nest one or two levels if grouping is truly needed.
2. Use Enums or Constants Instead of Raw Strings
Typos in string literals cause hard‑to‑find bugs:
const order = { status: "pending", paymentMethod: "credit card", shippingType: "express" };
if (order.status === "pendingg") { /* bug */ }Define an enum and reference it:
const OrderStatus = { PENDING: "pending", PROCESSING: "processing", SHIPPED: "shipped", DELIVERED: "delivered" };
const order = { status: OrderStatus.PENDING, paymentMethod: "credit_card", shippingType: "express" };
if (order.status === OrderStatus.PENDING) { /* IDE autocomplete helps */ }3. Store Dates with Timezone Information
Saving a plain date string without timezone leads to ambiguity:
const event = { name: "Team Meeting", startTime: "2024-03-15 14:30:00" };Use ISO‑8601 with UTC or store a timestamp:
const event = { name: "Team Meeting", startTime: "2024-03-15T14:30:00Z", timezone: "UTC" };
// or
const event = { name: "Team Meeting", startTimeMs: 1710512400000, timezone: "America/New_York" };Always include timezone data.
4. Validate JSON Structure
Assuming API data is always correct can crash your app:
function processUser(userData) {
return {
fullName: userData.firstName + " " + userData.lastName,
accountAge: Date.now() - userData.createdAt
};
}Add simple checks or use a schema library:
function processUser(userData) {
if (!userData || !userData.firstName || !userData.lastName) {
throw new Error("Invalid user data structure");
}
return {
fullName: userData.firstName + " " + userData.lastName,
accountAge: userData.createdAt ? Date.now() - userData.createdAt : null
};
}
// Libraries like Zod or Joi can provide richer validation.5. Keep Array Elements Homogeneous
Mixing types forces type checks everywhere:
const mixedData = { items: [ { id: 1, name: "Item 1" }, "special item", { id: 2, name: "Item 2" }, 42, { id: 3, name: "Item 3" } ] };Use a consistent shape and add a discriminator if needed:
const data = {
items: [
{ id: 1, name: "Item 1", type: "regular" },
{ id: 2, name: "Special Item", type: "special" },
{ id: 3, name: "Item 3", type: "regular" }
],
metadata: { specialCount: 1, totalCount: 3 }
};6. Never Store Sensitive Data in Plain JSON
Storing passwords or credit‑card numbers in clear text is dangerous:
const userSession = { userId: 123, username: "john_doe", password: "myPassword123", creditCard: "4532-1234-5678-9010" };
localStorage.setItem("session", JSON.stringify(userSession));Replace them with tokens and consider httpOnly cookies for storage:
const userSession = { userId: 123, username: "john_doe", token: "eyJhbGciOi...", expiresAt: 1710598800000 };
localStorage.setItem("session", JSON.stringify(userSession));7. Use a Consistent Naming Convention
Inconsistent keys cause confusion:
const response = { user_id: 123, firstName: "John", last_name: "Doe", EmailAddress: "[email protected]", phone_number: "555-0123" };Adopt camelCase for JavaScript projects:
const response = { userId: 123, firstName: "John", lastName: "Doe", emailAddress: "[email protected]", phoneNumber: "555-0123" };If the backend uses snake_case, convert at the API boundary.
function toApiFormat(data) { return { user_id: data.userId, first_name: data.firstName, last_name: data.lastName }; }
function fromApiFormat(data) { return { userId: data.user_id, firstName: data.first_name, lastName: data.last_name }; }8. Add Comments to Configuration Files
JSON does not support comments. Use JSON5/JSONC or switch to YAML/TOML for annotated configs:
{
// This is the API endpoint for production
"apiUrl": "https://api.example.com",
// Feature flags
"features": {
"newDashboard": true, // Enabled in v2.0
"betaFeatures": false
}
}9. Handle Large JSON Objects Efficiently
Parsing a huge JSON string blocks the main thread: const data = JSON.parse(hugeJsonString); Use streaming parsers for large files:
const fs = require('fs');
const JSONStream = require('JSONStream');
fs.createReadStream('large-file.json')
.pipe(JSONStream.parse('items.*'))
.on('data', item => { processItem(item); });Alternatively, paginate API responses.
10. Version Your JSON APIs
Changing a response shape without versioning breaks clients:
{ "name": "John Doe", "email": "[email protected]" }
// Breaking change
{ "firstName": "John", "lastName": "Doe", "email": "[email protected]" }Introduce a version field or separate endpoint versions:
{ "version": "2.0", "data": { "firstName": "John", "lastName": "Doe", "email": "[email protected]" } }
// or /api/v1/users vs /api/v2/usersConclusion
JSON is simple, but careless use leads to bugs and maintenance headaches. Paying attention to structure, naming, validation, timezone handling, and versioning yields more robust and maintainable code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
