NeuroAgent

How to Access Query String Parameters in Express.js

Learn how to access and parse query string parameters in Express.js using req.query object. Compare with PHP's $_GET and discover best practices for validation and handling multiple values.

Question

How to access query string parameters in Express.js on Node.js?

Can we retrieve query string variables in Node.js similar to how we access them through $_GET in PHP?

I understand that Node.js provides access to the URL in the request object. What is the proper method to extract and access query string parameters in Express.js?

NeuroAgent

In Express.js, query string parameters are accessed through the req.query object, which automatically parses the URL query string into a JavaScript object containing key-value pairs. This is fundamentally different from PHP’s $_GET as it’s a native JavaScript object rather than a superglobal array, but provides similar functionality for accessing URL parameters. The Express framework handles all URL parsing automatically, making query parameter retrieval straightforward and consistent across different routes.

Contents

Basic Query Parameter Access

Express.js provides the most straightforward method for accessing query string parameters through the req.query property. This property is automatically populated by Express when a request comes in, containing all the parsed query string parameters as key-value pairs in a JavaScript object.

The fundamental syntax is:

javascript
req.query.parameterName

For example, given a URL like http://localhost:3000/?name=John&age=25, the req.query object would contain:

javascript
{
  name: "John",
  age: "25"
}

You can access individual parameters directly:

javascript
const express = require("express");
const app = express();

app.get("/", function (req, res) {
  res.send(`Your name is ${(req.query.name || "").length} characters long`);
});

app.listen(3000);

According to the official Express documentation, the req.query object is the result of parsing the URL query string, or an empty object if there is no query string. This approach is consistent across all Express route handlers.


Handling Arrays and Multiple Values

One of the powerful features of Express.js query parameter handling is its automatic support for arrays and multiple values. When a query parameter appears multiple times in the URL, Express automatically converts it into an array.

For example, with the query string ?color=black&color=yellow, the req.query object becomes:

javascript
{
  color: ["black", "yellow"]
}

This behavior is demonstrated in the Mastering JS tutorial, which shows how Express handles multiple values for the same parameter name:

javascript
const app = require('express')();
app.get('*', (req, res) => {
  req.query; // { color: ['black', 'yellow'] }
  res.json(req.query);
});

When working with arrays, you should always check if the result is actually an array:

javascript
app.get('/fruits', (req, res) => {
  const { filterBy = [] } = req.query;
  console.log(Array.isArray(filterBy)); // true
  // Now you can safely use array methods
  const filteredItems = originalItems.filter(item => filterBy.includes(item.type));
  res.json(filteredItems);
});

If you need to handle nested objects in query strings, Express also supports this through dot notation. For example, ?user[name]=John&user[age]=25 would result in:

javascript
{
  user: {
    name: "John",
    age: "25"
  }
}

Advanced Validation and Best Practices

While basic query parameter access is straightforward, production applications often require robust validation and sanitization of query parameters. The express-validator library provides comprehensive validation middleware specifically designed for this purpose.

Basic Validation with express-validator

javascript
const { checkSchema, validationResult } = require('express-validator');

app.get('/search', checkSchema({
  query: {
    in: 'query',
    isString: true,
    isLength: {
      options: { min: 3 }
    },
    errorMessage: 'Search query must be at least 3 characters long'
  },
  limit: {
    in: 'query',
    isInt: {
      options: { min: 1, max: 100 }
    },
    optional: true,
    errorMessage: 'Limit must be between 1 and 100'
  }
}), (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  
  // Proceed with validated parameters
  const { query, limit = 10 } = req.query;
  // ... your business logic
});

Schema-Based Validation

For more complex scenarios, schema-based validation offers a cleaner approach:

javascript
const { body, query, param } = require('express-validator');

const searchValidation = [
  query('filterBy').isArray().withMessage('Filter must be an array'),
  query('filterBy.*').isString().withMessage('Each filter must be a string')
];

app.get('/products', searchValidation, (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  
  const { filterBy = [] } = req.query;
  // Process array filters safely
});

As mentioned in the Scaler Topics guide, proper validation is crucial for building secure and reliable APIs. Key best practices include:

  1. Always validate user input - Never trust query parameters directly
  2. Set appropriate data types - Convert strings to numbers/booleans as needed
  3. Handle optional parameters gracefully - Provide default values
  4. Sanitize inputs - Remove potentially malicious content
  5. Validate array parameters - Ensure they conform to expected structure

Complete Examples and Implementation

Let’s explore a complete implementation that covers various scenarios for query parameter handling in Express.js.

Example 1: Basic Search Endpoint

javascript
const express = require('express');
const app = express();

// Search endpoint with multiple parameters
app.get('/api/search', (req, res) => {
  const { q, category, limit = 10, page = 1 } = req.query;
  
  // Basic validation
  if (!q || q.trim() === '') {
    return res.status(400).json({ error: 'Search query is required' });
  }
  
  // Convert limit and page to numbers
  const limitNum = parseInt(limit, 10);
  const pageNum = parseInt(page, 10);
  
  // Validate numeric parameters
  if (isNaN(limitNum) || limitNum < 1 || limitNum > 100) {
    return res.status(400).json({ error: 'Limit must be between 1 and 100' });
  }
  
  if (isNaN(pageNum) || pageNum < 1) {
    return res.status(400).json({ error: 'Page must be a positive number' });
  }
  
  // Process search logic here
  const results = performSearch(q, category, limitNum, pageNum);
  
  res.json({
    query: q,
    category,
    page: pageNum,
    limit: limitNum,
    results
  });
});

function performSearch(query, category, limit, page) {
  // Your search implementation here
  return [];
}

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Example 2: Filtering with Arrays

javascript
app.get('/api/products', (req, res) => {
  const { 
    categories = [], 
    priceRange, 
    sortBy = 'name', 
    sortOrder = 'asc' 
  } = req.query;
  
  // Handle categories array
  const categoryArray = Array.isArray(categories) ? categories : [categories].filter(Boolean);
  
  // Parse price range
  let minPrice = 0;
  let maxPrice = Infinity;
  
  if (priceRange) {
    const prices = priceRange.split('-').map(p => parseFloat(p.trim()));
    if (prices.length === 2 && !prices.some(isNaN)) {
      minPrice = prices[0];
      maxPrice = prices[1];
    }
  }
  
  // Validate sort parameters
  const validSortFields = ['name', 'price', 'rating'];
  const validSortOrders = ['asc', 'desc'];
  
  if (!validSortFields.includes(sortBy)) {
    return res.status(400).json({ error: 'Invalid sort field' });
  }
  
  if (!validSortOrders.includes(sortOrder)) {
    return res.status(400).json({ error: 'Invalid sort order' });
  }
  
  // Process filtering logic
  const filteredProducts = filterProducts({
    categories: categoryArray,
    minPrice,
    maxPrice,
    sortBy,
    sortOrder
  });
  
  res.json({
    filters: {
      categories: categoryArray,
      priceRange: `${minPrice}-${maxPrice}`,
      sortBy,
      sortOrder
    },
    products: filteredProducts
  });
});

Example 3: Using Middleware for Common Query Parameters

javascript
// Middleware to handle common pagination parameters
const paginateMiddleware = (req, res, next) => {
  const { page = '1', limit = '10' } = req.query;
  
  req.pagination = {
    page: Math.max(1, parseInt(page, 10)),
    limit: Math.min(100, Math.max(1, parseInt(limit, 10)))
  };
  
  next();
};

// Apply middleware to routes that need pagination
app.get('/api/users', paginateMiddleware, (req, res) => {
  const { page, limit } = req.pagination;
  const offset = (page - 1) * limit;
  
  // Get users with pagination
  const users = getUsers(limit, offset);
  
  res.json({
    page,
    limit,
    total: getTotalUsersCount(),
    users
  });
});

These examples demonstrate the flexibility and power of Express.js query parameter handling, from basic access to complex filtering and pagination scenarios.


Comparison with PHP’s $_GET

While both Express.js and PHP provide ways to access query string parameters, there are fundamental differences in their implementation and usage patterns.

Similarities

  • Both allow access to URL query parameters
  • Both support multiple values for the same parameter name
  • Both provide key-value access to parameters

Key Differences

1. Data Type and Structure

  • PHP $_GET: Returns an array of strings, even for numeric values
  • Express req.query: Returns a JavaScript object with proper type preservation (arrays remain arrays, numbers are strings unless converted)

2. Automatic Parsing

  • PHP: Built-in superglobal that’s always available
  • Express: Requires the Express framework and is available only within route handlers

3. Type Handling

  • PHP: All parameters are strings by default
  • Express: Maintains array structure when parameter names repeat

4. Access Pattern

php
// PHP
$name = $_GET['name'] ?? 'default';
$categories = $_GET['category'] ?? []; // Always an array
javascript
// Express.js
const name = req.query.name || 'default';
const categories = Array.isArray(req.query.category) ? req.query.category : [req.query.category].filter(Boolean);

5. Validation Requirements

  • PHP: Often requires manual validation and type casting
  • Express.js: Can leverage JavaScript’s dynamic typing and modern validation libraries

The Stack Overflow discussion provides practical examples of how Express.js query parameter access compares to traditional web frameworks.

Despite these differences, the core concept remains the same: both systems provide access to URL query parameters for server-side processing, with Express.js offering a more JavaScript-native approach that integrates seamlessly with modern web development practices.

Conclusion

Accessing query string parameters in Express.js is straightforward through the req.query object, which automatically parses URL query strings into JavaScript objects. This approach provides significant advantages over PHP’s $_GET by maintaining proper data types and array structures, making it more intuitive for JavaScript developers.

Key takeaways include:

  • Use req.query.parameterName for basic parameter access
  • Express automatically handles arrays when parameters repeat (e.g., ?color=red&color=blue)
  • Implement proper validation using libraries like express-validator for production applications
  • Convert string parameters to appropriate types (numbers, booleans) as needed
  • Handle optional parameters with default values using destructuring

For building robust APIs, always validate and sanitize query parameters before processing them, and consider implementing middleware for common patterns like pagination and filtering. The Express.js query parameter system provides the flexibility needed for modern web applications while maintaining simplicity for basic use cases.


Sources

  1. How to get GET (query string) variables in Express.js on Node.js - Stack Overflow
  2. Query Parameters in Express - Mastering JS
  3. Get Query Strings and Parameters in Express.js - Stack Abuse
  4. How do you access query parameters in an Express JS route handler? - GeeksforGeeks
  5. How to get query string params using Node and Express - Suraj Sharma
  6. Getting Query String Variables in Express.js - Tutorialspoint
  7. Reading Query Parameters in Node - GeeksforGeeks
  8. Query Parameter in Express - Scaler Topics
  9. How to handle query parameters in Node.js Express - APIDog
  10. Query parameters in Express - Stack Overflow