Table of Contents
- What is JSON?
- Why JSON?
- JSON Syntax
- JSON Data Types
- JSON Examples
- JSON in RESTful APIs
- JSON in NestJS
- Common JSON Operations
- JSON Best Practices
- Common Mistakes
- JSON Tools and Validation
What is JSON?
JSON stands for JavaScript Object Notation. It is a lightweight data-interchange format that is:
- Human-readable - Easy for humans to read and write
- Machine-readable - Easy for machines to parse and generate
- Language-independent - Works with any programming language
- Text-based - Stored as plain text
History
- Created by Douglas Crockford in the early 2000s
- Based on JavaScript object syntax
- Became an ECMA standard in 2013 (ECMA-404)
- Now the de facto standard for API data exchange
Key Characteristics
- ✅ Text format - Not binary, can be read by humans
- ✅ Structured data - Represents objects and arrays
- ✅ Self-describing - Data includes its own structure
- ✅ No comments - JSON doesn't support comments
- ✅ Case-sensitive - Property names are case-sensitive
Why JSON?
Advantages
-
Simple and Lightweight - Minimal syntax overhead - Smaller file sizes than XML - Fast to parse and generate
-
Universal Support - Supported by all modern programming languages - Built into JavaScript (native support) - Easy to work with in any environment
-
Web-Friendly - Perfect for web APIs - Works seamlessly with HTTP - Standard for RESTful services
-
Human-Readable - Easy to debug - Can be edited manually - Self-documenting structure
Comparison with Other Formats
| Format | Pros | Cons | Use Case |
|---|---|---|---|
| JSON | Simple, lightweight, web-friendly | No comments, no schema | APIs, web apps |
| XML | Schema support, comments | Verbose, complex | Enterprise, documents |
| YAML | Human-readable, comments | Less common, parsing complexity | Config files |
| CSV | Simple, spreadsheet-friendly | No structure, no types | Data export |
JSON Syntax
Basic Rules
- Data is in name/value pairs (key-value pairs)
- Data is separated by commas
- Curly braces
{}hold objects - Square brackets
[]hold arrays - Strings must use double quotes
"" - No trailing commas (except in some modern parsers)
Object Syntax
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
Key Points:
- Keys must be strings (in double quotes)
- Keys and values separated by colon :
- Pairs separated by commas ,
- No comma after last item
Array Syntax
[
"item1",
"item2",
"item3"
]
Key Points: - Items separated by commas - Can contain any JSON data type - No comma after last item
Nested Structures
{
"user": {
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York"
}
},
"hobbies": ["reading", "coding", "gaming"]
}
JSON Data Types
JSON supports 6 basic data types:
1. String
{
"name": "John Doe",
"message": "Hello, World!",
"empty": ""
}
Rules:
- Must be enclosed in double quotes ""
- Single quotes '' are NOT valid
- Supports escape sequences: \", \\, \n, \t, etc.
Escape Sequences:
{
"quote": "He said \"Hello\"",
"path": "C:\\Users\\John",
"newline": "Line 1\nLine 2",
"tab": "Column1\tColumn2"
}
2. Number
{
"integer": 42,
"negative": -10,
"decimal": 3.14,
"scientific": 1.5e10,
"zero": 0
}
Rules:
- No leading zeros (except for decimals: 0.5)
- Can be integers or floating-point
- Can be negative
- No special values like Infinity or NaN
3. Boolean
{
"isActive": true,
"isDeleted": false
}
Rules:
- Only true or false (lowercase)
- Not True, TRUE, or 1
4. Null
{
"middleName": null,
"optionalField": null
}
Rules:
- Must be lowercase null
- Not NULL, None, or undefined
5. Object
{
"user": {
"name": "John",
"age": 30
}
}
Rules:
- Enclosed in curly braces {}
- Contains key-value pairs
- Can be nested
6. Array
{
"numbers": [1, 2, 3, 4, 5],
"names": ["John", "Jane", "Bob"]
}
Rules:
- Enclosed in square brackets []
- Items separated by commas
- Can contain mixed types
JSON Examples
Simple Object
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"active": true
}
Array of Objects
[
{
"id": 1,
"name": "John",
"age": 30
},
{
"id": 2,
"name": "Jane",
"age": 25
}
]
Complex Nested Structure
{
"company": {
"name": "Tech Corp",
"founded": 2020,
"employees": [
{
"id": 1,
"name": "John Doe",
"role": "Developer",
"skills": ["JavaScript", "TypeScript", "Node.js"],
"active": true,
"salary": null
},
{
"id": 2,
"name": "Jane Smith",
"role": "Designer",
"skills": ["UI/UX", "Figma", "Photoshop"],
"active": true,
"salary": 75000
}
],
"locations": {
"headquarters": {
"city": "San Francisco",
"country": "USA"
},
"offices": ["New York", "London", "Tokyo"]
}
}
}
Todo Example (NestJS Context)
{
"id": "1",
"title": "Learn NestJS",
"description": "Complete the NestJS tutorial",
"completed": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
API Request Body
{
"title": "New Todo",
"description": "Learn RESTful APIs",
"completed": false
}
API Response
{
"success": true,
"message": "Todo created successfully",
"data": {
"id": "1705312200000",
"title": "New Todo",
"description": "Learn RESTful APIs",
"completed": false,
"createdAt": "2024-01-15T12:30:00.000Z",
"updatedAt": "2024-01-15T12:30:00.000Z"
}
}
Error Response
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"field": "title",
"message": "Title is required"
}
]
},
"timestamp": "2024-01-15T12:30:00.000Z"
}
JSON in RESTful APIs
Request Body (POST/PUT)
When creating or updating resources, JSON is sent in the request body:
POST /todos HTTP/1.1
Content-Type: application/json
{
"title": "New Todo",
"description": "Learn JSON",
"completed": false
}
Response Body
API responses are typically JSON:
HTTP/1.1 201 Created
Content-Type: application/json
{
"success": true,
"data": {
"id": "1",
"title": "New Todo",
"completed": false
}
}
Query Parameters vs JSON Body
Query Parameters (GET requests):
GET /todos?page=1&limit=10&status=active
- Used for filtering, pagination, sorting
- Visible in URL
- Limited data size
JSON Body (POST/PUT requests):
{
"title": "New Todo",
"description": "Description here"
}
- Used for complex data
- Not visible in URL
- Can handle large data
JSON in NestJS
Automatic Serialization
NestJS automatically converts JavaScript objects to JSON:
@Get()
findAll() {
return {
success: true,
data: this.todosService.findAll()
};
}
What happens:
1. Controller returns JavaScript object
2. NestJS automatically serializes to JSON
3. Sets Content-Type: application/json header
4. Sends JSON string to client
Request Body Parsing
NestJS automatically parses JSON request bodies:
@Post()
create(@Body() createTodoDto: CreateTodoDto) {
// createTodoDto is already a JavaScript object
// NestJS parsed the JSON automatically
return this.todosService.create(createTodoDto);
}
What happens:
1. Client sends JSON string in request body
2. Express.js (underlying framework) parses JSON
3. @Body() decorator extracts the parsed object
4. NestJS maps to DTO class
5. Method receives JavaScript object
Date Serialization
JavaScript Date objects are automatically converted to ISO strings:
// In service
const todo = {
id: '1',
createdAt: new Date(), // JavaScript Date object
updatedAt: new Date()
};
// In JSON response
{
"id": "1",
"createdAt": "2024-01-15T10:30:00.000Z", // ISO string
"updatedAt": "2024-01-15T10:30:00.000Z"
}
Example: Complete Request-Response Cycle
1. Client sends JSON:
POST /todos
{
"title": "Learn JSON",
"description": "Understand JSON format"
}
2. NestJS receives and parses:
// Automatically parsed to:
{
title: "Learn JSON",
description: "Understand JSON format"
}
3. Service processes:
create(createTodoDto: CreateTodoDto) {
const todo = {
id: Date.now().toString(),
...createTodoDto,
completed: false,
createdAt: new Date(),
updatedAt: new Date()
};
return todo;
}
4. NestJS serializes response:
{
"success": true,
"data": {
"id": "1705312200000",
"title": "Learn JSON",
"description": "Understand JSON format",
"completed": false,
"createdAt": "2024-01-15T12:30:00.000Z",
"updatedAt": "2024-01-15T12:30:00.000Z"
}
}
Common JSON Operations
JavaScript: Parse JSON String
// JSON string (from API or file)
const jsonString = '{"name":"John","age":30}';
// Parse to JavaScript object
const obj = JSON.parse(jsonString);
console.log(obj.name); // "John"
console.log(obj.age); // 30
JavaScript: Convert Object to JSON
// JavaScript object
const obj = {
name: "John",
age: 30,
active: true
};
// Convert to JSON string
const jsonString = JSON.stringify(obj);
console.log(jsonString);
// '{"name":"John","age":30,"active":true}'
Pretty Print JSON
const obj = { name: "John", age: 30 };
// Pretty print with indentation
const pretty = JSON.stringify(obj, null, 2);
console.log(pretty);
// {
// "name": "John",
// "age": 30
// }
Accessing JSON Data
// Parse JSON
const data = JSON.parse('{"user":{"name":"John","hobbies":["coding","reading"]}}');
// Access properties
console.log(data.user.name); // "John"
console.log(data.user.hobbies[0]); // "coding"
console.log(data.user.hobbies.length); // 2
Modifying JSON Data
// Parse JSON
const data = JSON.parse('{"name":"John","age":30}');
// Modify
data.age = 31;
data.city = "New York";
// Convert back to JSON
const updated = JSON.stringify(data);
// '{"name":"John","age":31,"city":"New York"}'
Fetch API with JSON
// GET request
fetch('/todos')
.then(response => response.json()) // Parse JSON response
.then(data => {
console.log(data);
});
// POST request
fetch('/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ // Convert object to JSON string
title: "New Todo",
completed: false
})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
JSON Best Practices
1. Use Consistent Naming
✅ Good:
{
"firstName": "John",
"lastName": "Doe",
"emailAddress": "john@example.com"
}
❌ Bad:
{
"first_name": "John",
"LastName": "Doe",
"email": "john@example.com"
}
Recommendation: Use camelCase for JavaScript/TypeScript projects.
2. Validate JSON Structure
Always validate JSON before processing:
try {
const data = JSON.parse(jsonString);
// Process data
} catch (error) {
console.error('Invalid JSON:', error);
}
3. Handle Errors Gracefully
{
"success": false,
"error": {
"code": "INVALID_JSON",
"message": "Malformed JSON in request body"
}
}
4. Use Meaningful Property Names
✅ Good:
{
"userId": 123,
"userName": "john_doe",
"createdAt": "2024-01-15T10:30:00.000Z"
}
❌ Bad:
{
"id": 123,
"name": "john_doe",
"date": "2024-01-15T10:30:00.000Z"
}
5. Include Metadata in Responses
{
"success": true,
"data": [...],
"meta": {
"page": 1,
"limit": 10,
"total": 100
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
6. Use Consistent Response Format
Success Response:
{
"success": true,
"data": {...}
}
Error Response:
{
"success": false,
"error": {...}
}
7. Avoid Deep Nesting
✅ Good (2-3 levels):
{
"user": {
"profile": {
"name": "John"
}
}
}
❌ Bad (too deep):
{
"level1": {
"level2": {
"level3": {
"level4": {
"level5": {
"data": "value"
}
}
}
}
}
}
Common Mistakes
1. Using Single Quotes
❌ Invalid JSON:
{
'name': 'John'
}
✅ Valid JSON:
{
"name": "John"
}
2. Trailing Commas
❌ Invalid JSON (in strict mode):
{
"name": "John",
"age": 30,
}
✅ Valid JSON:
{
"name": "John",
"age": 30
}
3. Unquoted Keys
❌ Invalid JSON:
{
name: "John",
age: 30
}
✅ Valid JSON:
{
"name": "John",
"age": 30
}
4. Comments
❌ Invalid JSON:
{
"name": "John",
// This is a comment - NOT ALLOWED
"age": 30
}
✅ Valid JSON:
{
"name": "John",
"age": 30
}
5. Undefined Values
❌ Invalid JSON:
{
"name": "John",
"middleName": undefined
}
✅ Valid JSON:
{
"name": "John",
"middleName": null
}
6. Functions
❌ Invalid JSON:
{
"name": "John",
"greet": function() { return "Hello"; }
}
✅ Valid JSON:
{
"name": "John",
"greeting": "Hello"
}
7. Date Objects
❌ Invalid JSON:
{
"createdAt": new Date()
}
✅ Valid JSON:
{
"createdAt": "2024-01-15T10:30:00.000Z"
}
JSON Tools and Validation
Online Validators
-
JSONLint - https://jsonlint.com/ - Validates JSON syntax - Formats JSON - Shows errors clearly
-
JSON Formatter - https://jsonformatter.org/ - Pretty prints JSON - Validates syntax - Minifies JSON
Browser DevTools
Chrome/Firefox:
// In browser console
const json = '{"name":"John"}';
JSON.parse(json); // Validates and parses
VS Code Extensions
- JSON Tools - Format and validate JSON
- JSON Schema - Validate against schemas
- Prettier - Auto-format JSON files
Command Line Tools
Using Node.js:
node -e "JSON.parse(require('fs').readFileSync('data.json'))"
Using jq (Linux/Mac):
cat data.json | jq .
Validation in Code
function isValidJSON(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
// Usage
console.log(isValidJSON('{"name":"John"}')); // true
console.log(isValidJSON('{name:"John"}')); // false
Summary
Key Takeaways
- JSON is a text format for representing structured data
- Six data types: string, number, boolean, null, object, array
- Must use double quotes for strings and keys
- No comments, no functions, no undefined
- NestJS handles JSON automatically - parse and serialize
- Always validate JSON before processing
- Use consistent naming conventions
- Handle errors gracefully
JSON in NestJS Workflow
Client (JavaScript Object)
↓
JSON.stringify() → JSON String
↓
HTTP Request Body
↓
Express.js parses → JavaScript Object
↓
@Body() decorator → DTO Object
↓
Service processes
↓
Controller returns Object
↓
NestJS serializes → JSON String
↓
HTTP Response Body
↓
Client receives JSON
↓
JSON.parse() → JavaScript Object
Quick Reference
| Operation | JavaScript | NestJS |
|---|---|---|
| Parse JSON | JSON.parse(str) |
Automatic (Express.js) |
| Stringify | JSON.stringify(obj) |
Automatic (NestJS) |
| Request Body | Manual parsing | @Body() decorator |
| Response | Manual stringify | Automatic serialization |
| Date Handling | Manual conversion | Automatic (ISO string) |
Practice Exercises
Exercise 1: Validate JSON
Create a function to validate JSON strings:
function validateJSON(str) {
// Your code here
}
Exercise 2: Transform Data
Convert this JavaScript object to JSON and back:
const todo = {
id: 1,
title: "Learn JSON",
completed: false,
createdAt: new Date()
};
Exercise 3: Parse API Response
Given this JSON response, extract the todo data:
{
"success": true,
"data": {
"id": "1",
"title": "Learn JSON",
"completed": false
}
}
Remember: JSON is the language of APIs. Master JSON, and you'll master API communication! 🚀