JavaScript · API · Beginner

Headers and the Echo Endpoint

5 tasks

Add custom HTTP headers to requests and use the echo endpoint to inspect what you send.

HTTP headers

#
HTTP headers are key-value pairs that travel alongside a request or response — they carry metadata like content type, auth tokens, and custom information. In `fetch`, you set request headers in the options object: ```javascript const response = await fetch(url, { headers: { 'Authorization': 'Token abc123', 'X-Custom-Header': 'my-value', }, }); ``` You can also use the `Headers` class for a more structured approach: ```javascript const headers = new Headers(); headers.set('Authorization', 'Token abc123'); headers.set('X-Request-ID', '42'); const response = await fetch(url, { headers }); ``` The `/api/echo/` endpoint reflects back exactly what you sent — it's useful for verifying that headers arrive as expected: ```javascript const response = await fetch('https://apilearn.tukas.dev/api/echo/', { headers: { 'X-Custom-Header': 'hello' }, }); const data = await response.json(); // data.headers contains the headers the server received console.log(data.headers['X-Custom-Header']); // "hello" ``` The echo endpoint returns: ```javascript { method: "GET", headers: { /* all request headers */ }, body: null, query_params: {} } ```

Using the echo endpoint

#
Inspect what headers you're actually sending: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function inspectHeaders() { const response = await fetch(`${BASE_URL}/api/echo/`, { headers: { 'X-My-Header': 'test-value', 'X-Request-ID': '123', }, }); const data = await response.json(); console.log('Method:', data.method); console.log('My header:', data.headers['X-My-Header']); console.log('All headers:', data.headers); } inspectHeaders(); ``` A helper that builds a `fetch` wrapper with default headers: ```javascript function createClient(baseUrl, token) { const defaultHeaders = { 'Authorization': `Token ${token}`, 'Content-Type': 'application/json', }; return async function apiFetch(path, options = {}) { const response = await fetch(`${baseUrl}${path}`, { ...options, headers: { ...defaultHeaders, ...options.headers }, }); return response.json(); }; } // Usage — token will be shown in a later topic const client = createClient(BASE_URL, 'YOUR_TOKEN'); const profile = await client('/api/users/profile/'); console.log(profile.username); ``` Verify `Content-Type` is set when sending JSON: ```javascript const response = await fetch(`${BASE_URL}/api/echo/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'value' }), }); const echo = await response.json(); console.log(echo.headers['Content-Type']); // "application/json" ```

Headers and echo reference

#
**Setting headers in fetch** ```javascript // Object literal (simplest) fetch(url, { headers: { 'X-Key': 'value' } }) // Headers class const headers = new Headers({ 'X-Key': 'value' }); headers.set('X-Other', 'val2'); fetch(url, { headers }) ``` **Common headers** ``` Authorization Token auth: "Token <token>" JWT: "Bearer <access_token>" Content-Type For POST/PATCH/PUT with JSON body: "application/json" X-* Any custom header starting with X- ``` **Echo endpoint** ``` GET /api/echo/ Returns request details back as JSON ``` **Echo response shape** ```javascript { method: "GET", path: "/api/echo/", query_params: {}, headers: { "X-My-Name": "Alice", // custom headers keep original case ... }, body: null, content_type: null, auth: { authenticated: false, type: null, user: null, user_id: null } } ``` **Custom header casing** ``` The server returns custom headers with their original case. "X-My-Name" stays "X-My-Name" in the echo response. ``` **Merge default + per-request headers** ```javascript const merged = { ...defaultHeaders, ...requestHeaders }; ```
01

Send a custom header

#

Send a GET request to `/api/echo/` with a custom header `X-My-Name: YourName`. Print the value of that header from the echo response.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // GET /api/echo/ with X-My-Name header
  // print the echoed header value
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/echo/`, {
    headers: { 'X-My-Name': 'Alice' },
  });
  const data = await response.json();
  console.log(data.headers['X-My-Name']);
}

main();
02

Send multiple headers

#

Send GET `/api/echo/` with three headers: `X-App: my-app`, `X-Version: 1.0`, and `X-Request-ID: 42`. Print the full `headers` object from the response.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // send 3 custom headers, print data.headers
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/echo/`, {
    headers: {
      'X-App': 'my-app',
      'X-Version': '1.0',
      'X-Request-ID': '42',
    },
  });
  const data = await response.json();
  console.log(data.headers);
}

main();
03

Inspect method and query params via echo

#

Send GET `/api/echo/?color=blue&size=large`. Print the method and the `query_params` object from the response.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // GET /api/echo/ with two query params
  // print method and query_params
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const params = new URLSearchParams({ color: 'blue', size: 'large' });
  const response = await fetch(`${BASE_URL}/api/echo/?${params}`);
  const data = await response.json();
  console.log(data.method);
  console.log(data.query_params);
}

main();
04

POST with Content-Type header

#

Send POST to `/api/echo/` with a JSON body `{name: "test"}` and the `Content-Type: application/json` header. Print the echoed `Content-Type` header and the `body` field.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // POST /api/echo/ with JSON body and Content-Type header
  // print the content-type header and body from response
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/echo/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name: 'test' }),
  });
  const data = await response.json();
  console.log(data.headers['content-type'] ?? data.headers['Content-Type']);
  console.log(data.body);
}

main();
05

Use the Headers class

#

Build a `Headers` object with `.set()`, add at least two custom headers, then pass it to a GET `/api/echo/` request. Print the echoed headers.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const headers = new Headers();
  // add headers with .set()
  // fetch and print echoed headers
}

main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const headers = new Headers();
  headers.set('X-Client', 'js-api-course');
  headers.set('X-Version', '2.0');

  const response = await fetch(`${BASE_URL}/api/echo/`, { headers });
  const data = await response.json();
  console.log(data.headers);
}

main();