Implement User Filtering

Filtering allows users to retrieve records matching specific conditions.

For example:

GET /api/v1/users?isActive=true

GET /api/v1/users?role=admin

GET /api/v1/users?minAge=18&maxAge=30

The API should build MongoDB filters using explicitly supported query parameters.

Never pass the entire req.query object directly into a MongoDB query because clients may inject unexpected operators or fields.

Build User Filters
export function buildUserFilters(query) {
  const filter = {};

  if (query.role && ['user', 'admin'].includes(query.role)) {
    filter.role = query.role;
  }

  if (query.isActive === 'true') {
    filter.isActive = true;
  } else if (query.isActive === 'false') {
    filter.isActive = false;
  }

  const minAge = Number(query.minAge);
  const maxAge = Number(query.maxAge);

  if (query.minAge || query.maxAge) {
    filter.age = {};

    if (Number.isInteger(minAge)) filter.age.$gte = minAge;
    if (Number.isInteger(maxAge)) filter.age.$lte = maxAge;
  }

  return filter;
}

Creates a MongoDB filter using an explicit allowlist of supported query parameters.

Key Takeaways
  • Build filters from explicitly supported parameters.

  • Convert query values to appropriate data types.

  • Never pass arbitrary client query objects directly into MongoDB.