Navigation

Node.js

How to Handle Optional Parameters in Express Routes

Create flexible Express.js routes with optional parameters using question marks and regex patterns. Handle routes that work with or without certain parameters.

Table Of Contents

Problem

You need to create routes that work with optional parameters, like /users and /users/123, or /search and /search/category/electronics without duplicating route definitions.

Solution

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

// Method 1: Optional parameter with ?
app.get('/users/:id?', (req, res) => {
  const userId = req.params.id;
  
  if (userId) {
    // GET /users/123
    res.json({ 
      message: `User details for ID: ${userId}`,
      user: { id: userId, name: 'John Doe' }
    });
  } else {
    // GET /users
    res.json({ 
      message: 'All users',
      users: [
        { id: 1, name: 'John' },
        { id: 2, name: 'Jane' }
      ]
    });
  }
});

// Method 2: Multiple optional parameters
app.get('/search/:query?/:category?', (req, res) => {
  const { query, category } = req.params;
  
  let result = {
    query: query || 'all',
    category: category || 'general',
    results: []
  };
  
  if (query && category) {
    // GET /search/laptop/electronics
    result.results = [`${query} in ${category}`];
  } else if (query) {
    // GET /search/laptop
    result.results = [`${query} in all categories`];
  } else {
    // GET /search
    result.results = ['All items'];
  }
  
  res.json(result);
});

// Method 3: Using regex for complex optional patterns
app.get(/^\/products\/?(\d+)?\/?$/, (req, res) => {
  const productId = req.params[0]; // First capture group
  
  if (productId) {
    res.json({ 
      message: `Product ${productId}`,
      product: { id: productId, name: 'Sample Product' }
    });
  } else {
    res.json({ 
      message: 'All products',
      products: ['Product 1', 'Product 2']
    });
  }
});

// Method 4: Separate routes with shared logic
const handleArticles = (req, res) => {
  const { category, slug } = req.params;
  
  if (category && slug) {
    res.json({ 
      type: 'specific article',
      category,
      slug,
      article: `Article: ${slug} in ${category}`
    });
  } else if (category) {
    res.json({ 
      type: 'category articles',
      category,
      articles: [`Articles in ${category}`]
    });
  } else {
    res.json({ 
      type: 'all articles',
      articles: ['All articles']
    });
  }
};

app.get('/articles', handleArticles);
app.get('/articles/:category', handleArticles);
app.get('/articles/:category/:slug', handleArticles);

// Method 5: Using query parameters as alternative
app.get('/api/posts', (req, res) => {
  const { category, author, limit = 10 } = req.query;
  
  let filters = {};
  if (category) filters.category = category;
  if (author) filters.author = author;
  
  res.json({
    message: 'Posts with optional filters',
    filters,
    limit: parseInt(limit),
    posts: ['Post 1', 'Post 2']
  });
});

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

Example requests:

# Optional parameter routes
curl http://localhost:3000/users          # All users
curl http://localhost:3000/users/123      # Specific user

# Multiple optional parameters  
curl http://localhost:3000/search                    # All items
curl http://localhost:3000/search/laptop             # Search laptop
curl http://localhost:3000/search/laptop/electronics # Search in category

# Query parameters
curl "http://localhost:3000/api/posts?category=tech&author=john&limit=5"

Explanation

Adding ? after a parameter name makes it optional (:id?). The parameter will be undefined if not provided. For multiple optional parameters, each gets its own ?.

Regex routes offer more control but are harder to read. Query parameters (?category=tech) are often better for optional filters since they're more flexible and don't require specific URL patterns. Choose the method that best fits your API design and user experience needs.

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Node.js