KAHIBARO
Discord Login Register

6.4. Query Parameters

Understanding Query Parameters

When you build web backends, query parameters are one of the most common ways that clients send extra information with a request. You will see them everywhere, for example when searching, filtering, sorting, or paginating data.

This chapter focuses on what query parameters are, how they differ from other types of parameters, and how to use them correctly, with many concrete examples.


What Are Query Parameters?

A query parameter is a key value pair that appears in the URL after a question mark ?.

Basic structure:

text
https://example.com/search?query=python&limit=10

Breakdown:

In general, a URL with query parameters looks like this:

text
/path?key1=value1&key2=value2&key3=value3

Each key=value pair is one query parameter.

Rule: Query parameters always appear after ? in the URL and are separated by &.
Rule: Query parameters are not part of the path. They are optional and can appear in any order.


Query Parameters vs Path Parameters

You have already seen path parameters in routing. Path parameters are part of the path itself, for example:

text
/users/123

Here 123 might be a path parameter that identifies a specific user.

Query parameters are not part of the path, but are attached after ?:

text
/users?active=true&limit=20

Conceptual difference

You can combine both:

text
/users/123/orders?status=delivered&limit=10

Here:

A useful mental rule:

Rule: Use path parameters to say which resource.
Use query parameters to say how you want it.


Common Uses of Query Parameters

Query parameters are typically used for:

  1. Filtering
    • Example:
text
     /products?category=books&price_max=20
  1. Sorting
    • Example:
text
     /products?sort=price_asc
  1. Pagination
    • Example:
text
     /products?page=2&page_size=50
  1. Searching
    • Example:
text
     /search?query=laptop&in_stock=true
  1. Optional flags
    • Example:
text
     /users/123?include=orders,profile

Using query parameters for these things keeps your path clean and shows clearly that these are optional modifiers, not the main resource identifier.


Anatomy of a Query String

Consider this URL:

text
https://api.example.com/articles?author=alice&tag=python&tag=web&sort=recent&page=3

Break it into a table:

PartExampleMeaning
Path/articlesMain resource
authorauthor=aliceFilter by author
tag (1)tag=pythonOne tag filter
tag (2)tag=webAnother tag filter
sortsort=recentSorting option
pagepage=3Pagination page

Important details:

URL Encoding Basics

URLs can only safely include certain characters. Others must be encoded.

For example, a space is not allowed directly in the query. It is encoded as + or %20.

Examples:

Original valueEncoded in URL
python backendpython+backend
fast apifast+api
C#C%23
a&ba%26b

So a search query like:

text
/search?query=python backend

actually looks like:

text
/search?query=python+backend

Your web framework and HTTP libraries usually handle this encoding and decoding for you. When you read the query parameter in code, you get back the decoded value.


Required vs Optional Query Parameters

By default, query parameters are optional. A client can decide whether to send them or not.

For example, suppose you design this endpoint:

text
GET /products?category=books

The client might call:

You need to decide what your backend will do when the parameter is missing:

Example: optional parameters with defaults

text
GET /products?category=books&limit=20

You could define:

So:

You must document these defaults in your API description.

Example: required query parameters

Sometimes, you intentionally make a query parameter required, for example:

text
GET /search?query=python

You might decide:

So:

Multiple Values for the Same Parameter

Clients can send the same query parameter key multiple times. How your backend framework exposes this depends on the framework.

Example URL:

text
/articles?tag=python&tag=web&tag=backend

Possible interpretations:

  1. The backend might treat tag as a list of values: ["python", "web", "backend"].
  2. Or if you only read the first value, you might only see "python".

As an API designer, you should choose a clear style and document it. Some options:

Both are common. Your backend code must handle whichever style you choose.

Table of common patterns:

Client URL styleBackend sees as
?tag=python&tag=web["python", "web"]
?tag=python,web"python,web" then split it
?tag[]=python&tag[]=web["python", "web"]

You do not have to support every style. Pick one and be consistent.


Designing Query Parameters

When you design query parameters, think about clarity and predictability.

Naming conventions

Use clear, descriptive names:

Avoid cryptic names like p, s, or q2.

Boolean parameters

Boolean query parameters often appear as:

Sometimes developers shorten this, for example:

That can be confusing. Prefer explicit values.

Sorting

Several patterns are common for sorting:

  1. Single parameter with pattern:
text
   /users?sort=name_asc
   /users?sort=name_desc
   /users?sort=-name  (minus sign for descending)
  1. Separate field and direction:
text
   /users?sort_by=name&sort_dir=asc

Choose one style and apply it everywhere in your API.

Pagination

Pagination is nearly always done with query parameters. Common patterns:

PatternExampleMeaning
page / page_size?page=2&page_size=50Page number and items per page
limit / offset?limit=50&offset=100Page size and offset from start
cursor based?cursor=abc123&limit=50Use a cursor token, not a numeric page index

You do not need cursor based pagination for beginners. Page / page_size is simple and widely used.


Query Parameters and the HTTP Method

You can technically use query parameters with any HTTP method, for example:

However, the most common use is with GET:

For example:

text
GET /users?country=US&active=true

In requests that modify data (POST, PUT, PATCH, DELETE), you usually put most of the input in the request body, and use query parameters only for control flags, such as:

text
POST /orders?send_email=true

Here:

This separation keeps URLs readable and makes clear what is core data and what is optional behavior.


Query Parameters vs Request Body

For a beginner, it is useful to compare query parameters with request bodies.

FeatureQuery ParametersRequest Body
LocationIn the URL after ?In the HTTP message body
Common useFilters, options, paginationMain data for create/update
Typical methodsMostly GETPOST, PUT, PATCH
Data formatSimple key value pairs (strings)JSON, form data, XML, etc.
Size limitOften limited by URL lengthUsually can be larger

Example:

text
GET /products?category=books&limit=10

Here:

Another example:

text
POST /products
Content-Type: application/json
{
  "name": "Clean Code",
  "category": "books",
  "price": 25.00
}

Here:

Examples of Query Parameter Usage

Simple filtering

text
GET /users?country=DE

Behavior:

Multiple filters

text
GET /users?country=DE&active=true&role=admin

Behavior:

Optional search

text
GET /articles?query=python
GET /articles

Behavior:

Pagination example

text
GET /articles?page=3&page_size=20

Backend logic, for example:

$$\text{offset} = (\text{page} - 1) \times \text{page\_size}$$

So:

The backend might run a query like:

Formula: For page based pagination,
$$\text{offset} = (\text{page} - 1) \times \text{page\_size}$$

Sorting example

text
GET /products?sort=price_asc
GET /products?sort=-created_at

Backend interpretation:

Multiple tags example

Option 1: repeated parameters:

text
GET /articles?tag=python&tag=backend

Option 2: comma separated:

text
GET /articles?tag=python,backend

Backend must convert these into a list internally, such as:

text
["python", "backend"]

Handling Query Parameters in Code (Conceptually)

Different web frameworks and languages have different syntax, but the ideas are the same.

Almost always, you:

  1. Read the query parameters from the request.
  2. Validate them (type check, ranges, allowed values).
  3. Apply them to your logic (filters, pagination, sorting).
  4. Provide defaults when a parameter is missing.

Conceptual pseudocode:

python
def list_products(request):
    category = request.query.get("category")      # str or None
    page = int(request.query.get("page", 1))      # default 1
    page_size = int(request.query.get("page_size", 20))  # default 20
    # Validate page_size
    if page_size > 100:
        page_size = 100   # or return an error
    # Calculate offset
    offset = (page - 1) * page_size
    # Use these values to query the database
    products = find_products(category=category, offset=offset, limit=page_size)
    return products

You do not need to know Python details here. The key steps apply in any backend language or framework.


Good Practices for Query Parameters

To finish, here are some practical guidelines.

Be consistent

Use the same parameter names and patterns across your whole API.

Prefer simple types

Keep query parameters simple:

Avoid complex JSON structures in the query string, such as:

text
?filter={"price":{"min":10,"max":50}}

This is hard to read, hard to encode, and often better handled in the request body if you really need complex filters.

Validate everything

Do not blindly trust any query parameter:

If something is wrong, return a clear error response with a helpful message.

Document your parameters

For each endpoint, document:

This will later be expressed more formally with tools like OpenAPI and Swagger, but the idea is the same.


You now know what query parameters are, how they differ from path parameters and request bodies, and how they are commonly used for filtering, sorting, searching, and pagination. In the next topics, you will see how to work with other request parts, such as request bodies and form data, in more detail.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!