Skip to main content
Node.js APIs Tutorial
CHAPTER 06 Beginner

Handling Requests and Responses

Updated: May 14, 2026
20 min read

# CHAPTER 6

Handling Requests and Responses

1. Introduction

An API is simply a conversation. The client speaks (the Request), and the server replies (the Response). In previous chapters, our server only replied with simple text using res.send(). However, modern applications (like React or mobile apps) do not understand plain text; they expect structured data. In this chapter, we will learn how to extract data from incoming requests, manipulate HTTP Status Codes, and return professionally formatted JSON responses.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Extract query strings from the Request object (req.query).
  • Understand and utilize HTTP Status Codes.
  • Return structured data using res.json().
  • Chain response methods elegantly.

3. Beginner-Friendly Explanation

Imagine walking into a high-end restaurant.
  1. 1. The Request (req): You hand the waiter a highly specific order ticket: "I want a steak (the URL path), medium rare, with no salt (the Query Strings)."
  1. 2. The Waiter (Express): Takes your ticket, reads the specific details, and gives it to the chef.
  1. 3. The Response (res): The waiter brings back the food perfectly plated (JSON format) and hands you a receipt that says "Success: Order Complete" (Status Code 200). If they are out of steak, the waiter returns immediately and says "Sorry, Sold Out" (Status Code 404).

4. Query Strings (req.query)

In Chapter 5, we learned about Route Parameters (/users/42). Sometimes, clients send optional filters at the end of a URL using a question mark ?. These are called Query Strings.
javascript
123456789
// URL: /api/search?keyword=express&sort=asc
app.get('/api/search', (req, res) => {
    
    // Express automatically parses everything after the '?' into an object
    const searchTerm = req.query.keyword; // "express"
    const sortOrder = req.query.sort;     // "asc"
    
    res.send(`Searching for ${searchTerm}, sorting by ${sortOrder}`);
});

5. Returning JSON Data

When an iOS app asks for a user's profile, sending back an HTML page or a plain string will crash the app. You must send JSON (JavaScript Object Notation). Express provides a beautiful method that automatically formats your data and sets the correct HTTP headers behind the scenes: res.json().
javascript
12345678910
app.get('/api/profile', (req, res) => {
    const userProfile = {
        name: "Alice",
        role: "Admin",
        isActive: true
    };
    
    // Express converts the JavaScript object into a JSON string!
    res.json(userProfile);
});

6. HTTP Status Codes

A professional API doesn't just send data; it sends a Status Code to tell the client's code *what happened*.
  • 200 OK: Everything went perfectly.
  • 201 Created: You successfully created new data in the database.
  • 400 Bad Request: The client sent invalid data (like an invalid email).
  • 401 Unauthorized: The client is not logged in.
  • 404 Not Found: The requested resource does not exist.
  • 500 Server Error: The database crashed or the code broke.

7. Chaining Status Codes and JSON

You can chain the status() method directly to the json() method to create professional API responses.
javascript
1234567891011121314151617
app.get('/api/products/:id', (req, res) => {
    const productId = req.params.id;
    
    if (productId === "99") {
        // ERROR: Send a 404 Status Code with an error message
        res.status(404).json({
            status: "error",
            message: "Product not found in the database"
        });
    } else {
        // SUCCESS: Send a 200 Status Code with the data
        res.status(200).json({
            status: "success",
            data: { id: productId, name: "Laptop" }
        });
    }
});

8. Backend Workflow: Standardizing Responses

When building an API for a frontend team (React/Vue/Angular), you must agree on a standardized JSON structure. If route A returns { message: "Success" } and route B returns { status: "ok" }, the frontend developers will go crazy. Always return an object with a status key, an optional message, and a data key containing the actual database payload.

9. Best Practices

  • Use the return Keyword: Notice in the example above, if productId === "99", we send a 404 response. However, the function continues executing! To prevent Express from trying to send a second response (which crashes the app), always write return res.status(404).json(...) when dealing with errors.

10. Common Mistakes

  • Mixing up Params and Query:
  • /api/users/5 -> Uses req.params.id (Requires a Route definition of /:id).
  • /api/users?id=5 -> Uses req.query.id (Requires a Route definition of just /api/users).

11. Exercises

  1. 1. Explain the difference between res.send() and res.json(). Why is res.json() mandatory when building an API for a mobile application?

12. Coding Challenges

  • Challenge: Write a GET route for /api/weather. The route expects two query strings: city and units (e.g., ?city=London&units=metric). Extract these values. If the city is missing, return a 400 Bad Request JSON error. If both exist, return a 200 OK JSON response containing the simulated weather data.

13. MCQs with Answers

Question 1

A client visits the URL /api/flights?destination=Paris&airline=Delta. Which Express object contains the values "Paris" and "Delta"?

Question 2

When a client successfully creates a new account via a POST request, which HTTP Status Code should the server return?

14. Interview Questions

  • Q: Describe a standardized JSON response structure for a REST API. Why is it important for frontend developers that the backend maintains this consistent structure for both success and error responses?
  • Q: Explain the purpose of HTTP Status Codes. Give an example of a situation where you would return a 401 Unauthorized versus a 403 Forbidden.

15. FAQs

Q: Do I always have to specify res.status(200)? A: No. By default, if you just write res.json(), Express automatically attaches a 200 OK status code. You only need to explicitly define the status code if you are returning an error (4xx, 5xx) or a specific success state (201 Created).

16. Summary

In Chapter 6, we learned how to converse professionally with client applications. We extracted fine-grained search filters using req.query, replaced generic text responses with beautifully structured res.json() payloads, and utilized HTTP Status Codes to accurately communicate the success or failure of an operation.

17. Next Chapter Recommendation

Our routes are working, but what if we need to check if a user is logged in *before* letting them reach the route? Proceed to Chapter 7: Middleware in Express.js.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·