Table of Contents

  1. What is JSON?
  2. Why JSON?
  3. JSON Syntax
  4. JSON Data Types
  5. JSON Examples
  6. JSON in RESTful APIs
  7. JSON in NestJS
  8. Common JSON Operations
  9. JSON Best Practices
  10. Common Mistakes
  11. 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

  1. Simple and Lightweight - Minimal syntax overhead - Smaller file sizes than XML - Fast to parse and generate

  2. Universal Support - Supported by all modern programming languages - Built into JavaScript (native support) - Easy to work with in any environment

  3. Web-Friendly - Perfect for web APIs - Works seamlessly with HTTP - Standard for RESTful services

  4. 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

  1. Data is in name/value pairs (key-value pairs)
  2. Data is separated by commas
  3. Curly braces {} hold objects
  4. Square brackets [] hold arrays
  5. Strings must use double quotes ""
  6. 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

  1. JSONLint - https://jsonlint.com/ - Validates JSON syntax - Formats JSON - Shows errors clearly

  2. 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

  1. JSON is a text format for representing structured data
  2. Six data types: string, number, boolean, null, object, array
  3. Must use double quotes for strings and keys
  4. No comments, no functions, no undefined
  5. NestJS handles JSON automatically - parse and serialize
  6. Always validate JSON before processing
  7. Use consistent naming conventions
  8. 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! ๐Ÿš€