KAHIBARO
Discord Login Register

Searching

Why Searching Matters in APIs

Searching lets clients find specific data inside a larger collection of resources. In a REST API, you rarely return every record. Instead, you provide ways to search and narrow down results.

Consider a products API:

Searching is closely related to filtering and sorting. In many APIs, "search" means full text search, while "filtering" means field-based equality or ranges, but the boundary is not strict. In this chapter, we focus on patterns that are specific to search behavior, especially text search and user-facing queries.

Important idea: Searching should

  • be predictable,
  • use clear query parameters,
  • and not accidentally expose or overload your API.

Basic Searching with Query Parameters

The simplest style of search uses one or more query parameters on a collection endpoint.

Single search parameter

A common pattern for plain text search is a generic q or search parameter:

The meaning of this parameter must be documented, because different APIs treat it differently:

ExampleInterpretation
GET /books?q=pythonSearch title and description for the word "python"
GET /users?q=johnSearch name, username, or email containing "john"
GET /posts?q=errorSearch full text content of posts

You decide which fields q searches over. Once decided, keep it consistent.

Example: simple search behavior

Imagine an API:

http
GET /articles?q=fastapi

Server logic might be:

The response could include meta information about search:

json
{
  "query": "fastapi",
  "count": 2,
  "results": [
    { "id": 1, "title": "FastAPI basics" },
    { "id": 2, "title": "Deploying FastAPI" }
  ]
}

Here search is just a filter using "contains" semantics on text fields.

Multiple field-specific parameters

You can use more specific parameters to search by exact or partial match of fields:

Some APIs use a generic parameter name to indicate partial search and more specific names for exact search:

PatternMeaning
GET /users?name_contains=johnName contains "john"
GET /users?name=johnName equals "john"
GET /products?title_like=phoneTitle LIKE %phone% in SQL

This starts to mix searching and filtering, but it is common in real APIs.

Text Search vs Field Filters

You should distinguish between:

Both use query parameters, but you usually treat them differently in implementation and possibly in the database.

Typical combination

A common pattern looks like this:

http
GET /products?search=laptop&category=electronics&min_price=500&max_price=1500&sort=-price

Here:

You will often:

  1. Apply filters to narrow down the dataset.
  2. Apply text search on candidate records.
  3. Apply sorting and pagination to the final list.

This helps performance and keeps search behavior understandable.

Designing Search Parameters

There is no single standard, but some patterns are widely used and easy for clients to understand.

Common parameter names

Parameter nameTypical use
qGeneric search query, often full text search
searchSame as q, but more descriptive
queryMore verbose alternative, used in some APIs
termUsed when searching for a specific term or token
keywordsWhen search is based on multiple comma separated keywords

Choose one and stick with it. Many APIs pick q, others pick search.

Searching specific fields

You can support field specific search parameters, which is useful when you want precise control:

You can also support explicit "contains" or "starts with" behavior:

Example:

http
GET /users?name_contains=john&email_endswith=@example.com

This can be mapped to SQL LIKE operations, or to specific full text search operators depending on your database.

Combining generic and field searches

You may allow both a generic query and field specific parameters:

http
GET /jobs?q=backend&location=remote&company=acme

Design questions you must decide and document:

A clear rule is:

Rule: Apply all search and filter criteria together with logical AND,
so items must match all provided parameters, unless explicitly documented otherwise.

Pagination and Searching

Search results are often large. Always combine search with pagination.

For example:

http
GET /articles?q=python&page=2&limit=20

Here:

The response can include metadata:

json
{
  "query": "python",
  "page": 2,
  "limit": 20,
  "total": 85,
  "results": [ ... 20 articles ... ]
}

This is important for:

Search without pagination is a common performance mistake.

Implementing Simple Searching (Conceptually)

Without going deep into database details or any specific language, let us look at how simple search is often implemented.

Exact match vs partial match

Consider a users table with columns id, name, email.

If the API is:

http
GET /users?name=John

Server logic for an exact match could be:

sql
SELECT * FROM users WHERE name = 'John'

For partial match:

http
GET /users?name_contains=john

You might do:

sql
SELECT * FROM users WHERE LOWER(name) LIKE '%john%';

Lowercasing both sides makes the search case insensitive.

Simple multi field text search

For a generic q parameter searching both name and email:

http
GET /users?q=john

SQL style implementation:

sql
SELECT *
FROM users
WHERE LOWER(name)  LIKE '%john%'
   OR LOWER(email) LIKE '%john%';

This is basic and easy to understand, but not very powerful or efficient for large datasets.

Full Text Search Concepts

As your data grows, simple LIKE '%text%' search becomes slow and limited. Many systems provide full text search features that:

You do not need to implement full text search yourself, but you should know the API implications.

Ranking results

A full text search system can say:

Your API can expose this:

http
GET /articles?q=python performance

Response:

json
{
  "query": "python performance",
  "count": 3,
  "results": [
    { "id": 2, "title": "Python performance tips", "score": 0.95 },
    { "id": 5, "title": "Fast Python web APIs", "score": 0.78 },
    { "id": 7, "title": "General Python guide", "score": 0.40 }
  ]
}

You can sort by score descending by default.

Even if you use a database or search engine to compute the score, your REST API should present it in a simple and stable form.

Phrase search and operators

Some APIs accept more advanced search syntax in the q parameter:

Each extra feature makes the API more powerful but also more complex. For beginner APIs, stick to:

When you expose these features, document them clearly and test user input carefully, to avoid injection attacks or broken queries.

Search, Filtering, and Sorting Together

In a real backend, searching rarely stands alone. Clients want to:

Let us build an example for a "Job Listings" API.

Example: Job search endpoint

Endpoint:

http
GET /jobs

Supported query parameters:

ParameterTypeDescription
qstringText search on title and description
locationstringExact match on location name
remotebooleantrue or false
min_salaryintegerMinimum salary filter
max_salaryintegerMaximum salary filter
sortstringdate_posted, -date_posted, salary, etc
pageintegerPage number
limitintegerItems per page

Example request:

http
GET /jobs?q=backend&location=Berlin&remote=true&min_salary=60000&sort=-date_posted&page=1&limit=10

Server behavior conceptually:

  1. Start from all jobs.
  2. If q is provided, apply full text search on title and description.
  3. Apply filters: location, remote, salary range.
  4. Sort by date_posted descending.
  5. Paginate to page 1 with 10 items.

Response structure:

json
{
  "query": {
    "q": "backend",
    "location": "Berlin",
    "remote": true,
    "min_salary": 60000,
    "sort": "-date_posted",
    "page": 1,
    "limit": 10
  },
  "total": 43,
  "results": [
    {
      "id": 101,
      "title": "Senior Backend Developer",
      "location": "Berlin",
      "remote": true,
      "salary": 80000
    }
  ]
}

This pattern scales well as you add more search and filter options.

Handling Invalid or Ambiguous Searches

Search endpoints must handle user mistakes gracefully. Users often send:

Empty or missing search query

Examples:

You must define behavior, such as:

Consistent behavior prevents confusion.

Too generic or too long queries

A query like q=a or q=aaaaaaaaaaaaaaaaaaaaaaaaaa... may be expensive or unhelpful.

You can:

Example API rule:

Rule: If q is provided, its length must be between 3 and 100 characters.
Otherwise, return 400 Bad Request with a clear error message.

Example response:

json
{
  "detail": "Query parameter 'q' must be at least 3 characters long."
}

Invalid parameter types

If you expect integers for pagination or for numeric filters:

You should:

This keeps search behavior predictable and helps clients fix mistakes quickly.

Security Considerations in Searching

Search features, especially text search, can open some security and performance issues.

Injection risks

If you build SQL queries directly from user input, like:

sql
WHERE title LIKE '%" + userInput + "%'

You risk SQL injection if not using parameters properly. Always:

Denial of service through expensive search

Attackers or buggy clients might:

Mitigations:

Information leakage

Search can sometimes reveal information accidentally. For example:

Always enforce authorization checks before performing search, just as you do for reading individual resources.

Designing Search Responses

Beyond simply returning results, you can include helpful metadata so clients can build user interfaces easily.

Common response fields

FieldPurpose
queryEcho the search text or parameters used
totalTotal number of matching items, independent of pagination
pageCurrent page number
limitNumber of items per page
resultsArray of matching resource objects
facetsOptional aggregation data like counts per category or tag

Example:

json
{
  "query": {
    "q": "python",
    "category": "books"
  },
  "total": 27,
  "page": 1,
  "limit": 10,
  "results": [ /* 10 books */ ]
}

Faceted search (high level)

Some APIs include summary information that helps users refine search:

json
{
  "query": "laptop",
  "total": 100,
  "facets": {
    "brand": [
      { "value": "Dell", "count": 35 },
      { "value": "HP", "count": 20 },
      { "value": "Lenovo", "count": 45 }
    ],
    "price_range": [
      { "value": "0-500", "count": 10 },
      { "value": "500-1000", "count": 60 },
      { "value": "1000+", "count": 30 }
    ]
  },
  "results": [ /* laptops */ ]
}

Facets are advanced, and often require a search engine like Elasticsearch, but they are useful to know about conceptually.

Examples of Search URLs

To consolidate the ideas, here is a table of example search requests and what they might mean in a typical REST API.

URLMeaning
GET /products?q=phoneFull text search "phone" in product name and description
GET /products?search=phone&category=electronicsSearch text "phone", then filter by category "electronics"
GET /users?name_contains=johnSearch for users whose name contains "john"
GET /users?email_endswith=@example.comSearch for users with email ending in @example.com
GET /articles?q=python%20performance&page=2&limit=5Search for "python performance", second page, 5 results per page
GET /jobs?q=backend&location=Berlin&remote=true&min_salary=60000&sort=-date_postedCombine text search, filters, and sorting for job listings
GET /books?title=clean%20code&author=martinField based search for exact title and author
GET /movies?title_startswith=star&year=1977Search for movies whose title starts with "star" and year is 1977
GET /orders?customer_id=123&search=refundFilter by customer, then search text "refund" in order notes or descriptions

You can use these patterns as a starting point for your own API search design.

Summary

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!