Back to Blog
Lesson 24 of the REST API Design: Design Your First Clean REST API course
API ArchitectureAugust 10, 20264 min read

Searching Resources: Implementing Partial Match Logic in REST APIs

Learn how to implement powerful search functionality in your REST API. Master partial match logic using query parameters to help users find tasks faster.

API DesignREST APISearchingBackend DevelopmentQuery Params
A row of partially burned matches on a white background, displaying a gradient of charring.

Previously in this course, we explored Introduction to Query Parameters: Modifying API Behavior and built upon that by Filtering Collections: How to Parse Query Params in REST APIs. While filtering allows users to narrow down data by exact attributes (like status), searching allows users to find resources based on fuzzy, free-text input.

In this lesson, we will extend our Task Manager API to support keyword-based searches, enabling users to find tasks by looking for substrings within their titles or descriptions.

Why Searching Differs from Filtering

Filtering is typically binary: a task is "completed" or it is not. Searching, however, is about relevance and discovery. When a user searches for "report," they expect to see tasks where "report" appears anywhere in the title or description.

Unlike filtering, which often uses exact matches, searching requires partial match logic. We aren't checking if title == 'report'; we are checking if title contains the string "report".

Designing the Search Endpoint

White keyboard keys spelling 'search' on a bold red surface, conceptual design with copyspace.

Since we are still operating on a collection of tasks, we don't need a new route. We should continue to use the existing GET /v1/tasks endpoint. By adding a q (or search) query parameter, we allow the client to request a filtered subset of the collection without creating bloated URL structures.

The Logic flow

  1. Extract: Capture the q query parameter from the request.
  2. Validate: Ensure the search string is not empty or overly long (to prevent malicious resource exhaustion).
  3. Query: Perform a case-insensitive partial match against the data store.
  4. Respond: Return the matching subset or an empty array if no matches are found.

Worked Example: Implementing Partial Match

Assuming a Node.js/Express environment, here is how you would implement this logic in your GET /tasks controller:

JAVASCRIPT
// GET /v1/tasks?q=urgent
app.get(CE9178">'/v1/tasks', (req, res) => {
  const { q } = req.query;
  let tasks = db.getTasks(); // Assume this retrieves all tasks

  if (q) {
    const searchTerm = q.toLowerCase();
    tasks = tasks.filter(task => 
      task.title.toLowerCase().includes(searchTerm) || 
      task.description.toLowerCase().includes(searchTerm)
    );
  }

  res.json({ data: tasks, meta: { count: tasks.length } });
});

In this example, we normalize both the task fields and the search term to lowercase. This ensures that a search for "Urgent" matches a title containing "urgent" or "URGENT", providing a better user experience.

Hands-on Exercise

Modify your current Task Manager API to implement the search logic shown above.

  1. Update your GET /v1/tasks endpoint to check for a q parameter.
  2. Ensure the search looks through both the title and description fields.
  3. Test the endpoint using Postman or cURL: GET /v1/tasks?q=fix.

Common Pitfalls

Close-up of a triangular warning sign indicating a slippery surface, fixed to a wooden post.

  • Case Sensitivity: Forgetting to normalize strings leads to "misses" where users expect hits. Always use .toLowerCase() or database-level case-insensitive operators (like ILIKE in PostgreSQL).
  • Performance at Scale: The .filter() method in the example above iterates through the entire dataset in memory. As your collection grows to thousands of items, this will become slow. In production, you should push this logic to your database using WHERE ... LIKE %term% queries.
  • Empty Search Terms: Always handle the case where the user sends ?q= (an empty string). Your logic should treat this as a request for all tasks, not a search for "empty" strings.

Frequently Asked Questions

Q: Should I use q or search as the parameter name? A: Both are common. q is standard in many search-heavy APIs (like GitHub or Google), while search is more explicit. Choose one and stick to it across your API.

Q: Can I combine filtering and searching? A: Absolutely. You can chain them: GET /v1/tasks?status=pending&q=urgent. Your code should handle status filtering first, then apply the q search to the resulting subset.

Recap

Team members presenting a project in a modern office setting with a focus on collaboration.

We've successfully moved from simple attribute filtering to text-based search. By using query parameters, we keep our API clean and intuitive. Remember to handle case sensitivity and consider database-level performance as your project grows.

Up next: Implementing Query Logic in Task Manager, where we will combine filtering, sorting, and searching into a single, cohesive request pipeline.

Similar Posts