node js api

Intermediate

Node.js API (Intermediate) Study Guide

Welcome! This guide will help you master Node.js API development at an intermediate level. We’ll cover core concepts, common interview questions, ideal answers, real-world examples, and study tips. Let’s dive in.


1. Core Concepts

1.1 Express.js Fundamentals

  • **What is Express.js?.js is a minimal and flexible Node.js framework for building web applications and APIs. It provides robust features like routing, middleware, and templating.

  • Key Components:

    • Routes: Define endpoints (e.g., GET /users, POST /login).
    • Middleware: Functions that have access to the request/response cycle (e.g., logging, authentication).
    • Error Handling: Centralized error handling using app.use((err, req, res, next) => {...}).
  • Example: Basic API Setup

    const express = require('express');
    const app = express();
    
    // Middleware to parse JSON bodies
    app.use(express.json());
    
    // Route example
    app.get('/api/users', (req, res) => {
      res.json({ message: 'List of users' });
    });
    
    // Start server
    app.listen(3000, () => console.log('Server running on port 3000'));
    

1.2 RESTful API Design

  • REST Principles:

    • Stateless: Each request contains all necessary information.
    • Client-Server: Separation of concerns.
    • Cacheable: Responses must define themselves as cacheable or not.
    • Uniform Interface: Use standard HTTP methods (GET, POST, PUT, DELETE).
  • Best Practices:

    • Use snake_case for URL parameters (e.g., /api/users/:user_id).
    • Return appropriate HTTP status codes (e.g., 200 OK, 404 Not Found, 401 Unauthorized).

1.3 Authentication & Authorization

  • JWT (JSON Web Tokens):

    • Used for stateless authentication.
    • Flow:
      1. User logs in with credentials.
      2. Server generates a JWT and sends it back.
      3. Client includes JWT in the Authorization header for subsequent requests.
      4. Server verifies the token.
  • Example: JWT Middleware

    const jwt = require('jsonwebtoken');
    
    const authenticate = (req, res, next) => {
      const token = req.headers.authorization?.split(' ')[1];
      if (!token) return res.status(401).json({ error: 'Access denied' });
    
      try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.user = decoded;
        next();
      } catch (err) {
        res.status(400).json({ error: 'Invalid token' });
      }
    };
    
    // Protected route
    app.get('/api/protected', authenticate, (req, res) => {
      res.json({ message: 'Protected data', user: req.user });
    });
    

1.4 Database Integration

  • SQL vs NoSQL:

    • SQL (e.g., PostgreSQL, MySQL): ACID compliance, structured data.
    • NoSQL (e.g., MongoDB): Flexible schema, horizontal scaling.
  • ORM/ODM Tools:

    • Sequelize (SQL) or Mongoose (MongoDB) for schema modeling and queries.
  • Example: Mongoose Model

    const mongoose = require('mongoose');
    
    const userSchema = new mongoose.Schema({
      username: { type: String, required: true, unique: true },
      email: { type: String, required: true },
      password: String
    });
    
    module.exports = mongoose.model('User', userSchema);
    

1.5 Error Handling & Validation

  • Centralized Error Handling:

    app.use((err, req, res, next) => {
      console.error(err.stack);
      res.status(500).json({ error: 'Something went wrong!' });
    });
    
  • Validation with express-validator:

    const { body, validationResult } = require('express-validator');
    
    app.post('/api/users',
      body('email').isEmail().normalizeEmail(),
      body('password').isLength({ min: 6 }),
      (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
          return res.status(400).json({ errors: errors.array() });
        }
        //Proceed to create user
      }
    );
    

2. Common Interview Questions & Ideal Answers

Q1: Explain Middleware in Express.js. Why is it important?

Ideal Answer:
Middleware functions have access to the request/response cycle. They’re used for tasks like:

  • Parsing request bodies (express.json()).
  • Authentication (authenticate()).
  • Logging (morgan).
  • Error handling.
    They enhance modularity, allowing you to plug in functionality without modifying core routes.

Q2: How would you handle asynchronous operations in routes?

Ideal Answer:
Use async/await with try/catch for better readability and error handling:

app.get('/api/data', async (req, res, next) => {
  try {
    const data = await fetchDataFromDB();
    res.json(data);
  } catch (err) {
    next(err); // Pass to error-handling middleware
  }
});

Q3: What is the difference between REST and GraphQL?

Ideal Answer:

  • REST:
    • Uses standard HTTP methods.
    • Clients request specific resources (URLs).
    • Over-fetching/Under-fetching issues.
  • GraphQL:
    • Single endpoint (/graphql).
    • Clients define the structure of the response.
    • Reduces over/under-fetching.
      Use Case: REST for simple CRUD; GraphQL for complex queries needing precise data.

Q4: How do you implement rate limiting in an API?

Ideal Answer:
Use express-rate-limit package:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per window
  message: 'Too many requests, please try again later'
});

app.use('/api/login', limiter);

3. Real-World Example: Building a User API

Scenario:

Create an API to register users, login, and fetch user profiles with JWT authentication.

Steps:

  1. Setup:

    • Initialize npm, install express, mongoose, jsonwebtoken, bcrypt, dotenv, express-validator.
  2. Models:

    • User.js (Mongoose model with hashed passwords).
  3. Routes:

    • POST /api/auth/register (validate input, hash password, save user).
    • POST /api/auth/login (check credentials, return JWT).
    • GET /api/profile (protected route, returns user data).
  4. Middleware:

    • authenticate.js (JWT verification).
  5. Error Handling:

    • Centralized error logger.

4. Study Tips

  1. Build Projects:

    • Create a blog API, e-commerce cart, or task manager.
    • Integrate real databases (PostgreSQL/MongoDB).
  2. Master Testing:

    • Use Jest or Mocha for unit/integration tests.
    • Test endpoints with Postman or Thunder Client.
  3. Learn Security:

    • Implement HTTPS, CORS, helmet, and CSRF protection.
  4. Understand Performance:

    • Learn caching (Redis), rate limiting, and load balancing.
  5. Review System Design:

    • Practice designing scalable APIs (e.g., “Design a Twitter-like API”).

Next Steps

  • Practice Coding: Implement the Real-World Example above.
  • Review System Design: Study microservices vs monoliths, API gateways, and database sharding.
  • Mock Interviews: Simulate Q&A on topics like error handling, JWT security, and RESTful design.

Ask any clarifying questions or request deeper dives into specific areas!

Ready for a new challenge?

Start a new session to explore different topics or increase the difficulty level.

Start New Session