Query Params, Headers, and Auth
Real API requests often need more than a URL.
You may need:
- query parameters
- headers
- authentication tokens
- pagination options
- filters
Query Parameters
Query parameters appear after ? in a URL.
/api/products?category=books&page=2They are often used for:
- search
- filters
- sorting
- pagination
Example:
const response = await fetch("/api/products?category=books&page=2");Building Query Strings Safely
Use URLSearchParams.
const params = new URLSearchParams({
category: "books",
page: "2",
sort: "price",
});
const response = await fetch(`/api/products?${params.toString()}`);URLSearchParams handles encoding for you.
const params = new URLSearchParams({
q: "javascript basics",
});
console.log(params.toString()); // q=javascript+basicsRequest Headers
Headers send metadata with a request.
const response = await fetch("/api/users", {
headers: {
"Accept": "application/json",
},
});Common headers:
| Header | Purpose |
|---|---|
Accept |
tells server what response format you want |
Content-Type |
tells server what request body format you send |
Authorization |
sends authentication credentials |
Authorization Header
Many APIs use bearer tokens.
const token = "abc123";
const response = await fetch("/api/me", {
headers: {
"Authorization": `Bearer ${token}`,
},
});This tells the server who is making the request.
Never hard-code real secrets in frontend source code.
Frontend code is visible to users.
API Keys in Frontend Code
Be careful with API keys.
Public browser code cannot safely hide secrets.
If an API key must be secret, call that API from your backend instead.
Frontend-safe keys are usually restricted by domain, permissions, or quota.
Pagination Example
async function loadProducts({ page = 1, limit = 20, category }) {
const params = new URLSearchParams({
page: String(page),
limit: String(limit),
});
if (category) {
params.set("category", category);
}
const response = await fetch(`/api/products?${params}`);
if (!response.ok) {
throw new Error("Could not load products");
}
return response.json();
}Convert numbers to strings when building query params.
Combining Headers
async function createProduct(product, token) {
const response = await fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify(product),
});
if (!response.ok) {
throw new Error("Could not create product");
}
return response.json();
}This sends both JSON format information and authentication.
Best Practices
Use URLSearchParams for query strings.
Use headers intentionally.
Use Authorization for tokens when the API requires it.
Do not expose secret keys in frontend code.
Check API documentation for required params and headers.
Handle missing or expired authentication.
Common Mistakes
Mistake 1: Manually Concatenating Unsafe Query Strings
const url = "/api/search?q=" + searchText;Use:
const params = new URLSearchParams({ q: searchText });Mistake 2: Hard-Coding Secrets
const apiSecret = "real-secret-key";Frontend code is visible to users.
Mistake 3: Forgetting Bearer Prefix
Many APIs expect:
Authorization: Bearer tokennot just:
Authorization: tokenCheck the API docs.
Summary
Query params and headers make API requests more specific.
- Query params are used for filtering, searching, sorting, and pagination.
URLSearchParamsbuilds query strings safely.- Headers send metadata.
Content-Typedescribes request bodies.Authorizationcommonly sends auth tokens.- Do not expose secret API keys in frontend code.