pramas, body, payload and headers in axios/fetch

 

TermWhat is it?Where is it used?When to use it?
HeadersMetadata about the request or response. Key-value pairs.In all requests and responses.Authentication (Authorization: Bearer <token>), Content Type (Content-Type: application/json), Caching (Cache-Control).
Params (Query Parameters)Non-sensitive data appended to the URL after a ?.Primarily used for GET requests.Filtering, sorting, and pagination (e.g., .../users?**status=active&page=1**).
Body / PayloadThe actual data being sent to the server.Primarily used for POST, PUT, and PATCH requests.Creating or updating resources (e.g., sending user's name and email on a sign-up request). Note: These two terms are often used interchangeably to refer to the data sent in the request body.
URL PathThe main path of the resource.In all requests.Identifying the specific resource (e.g., /api/users/123).

 

 

 // lib/api-client-fetch.js

const BASE_URL = process.env.API_BASE_URL; // Use environment variables!

// Production-ready fetch wrapper
async function apiFetch(endpoint, options = {}) {
  // 1. Headers: Merge custom headers with defaults (like Content-Type and Auth)
  const defaultHeaders = {
    'Content-Type': 'application/json',
    // Best Practice: Get token from a secure, server-only source (e.g., cookies or Next.js headers() function)
    'Authorization': options.token ? `Bearer ${options.token}` : undefined,
  };

  const finalOptions = {
    ...options,
    headers: {
      ...defaultHeaders,
      ...options.headers, // Allow user to override or add new headers
    },
    // Next.js caching options for Server Components (e.g., force-cache, no-store, revalidate)
    next: options.next || { revalidate: 3600 } 
  };
  
  // 2. Body/Payload: Stringify the body for POST/PUT/PATCH requests
  if (finalOptions.body && typeof finalOptions.body !== 'string') {
    finalOptions.body = JSON.stringify(finalOptions.body);
  }

  const response = await fetch(`${BASE_URL}${endpoint}`, finalOptions);

  if (!response.ok) {
    // Production Grade Error Handling
    const errorBody = await response.json().catch(() => ({ message: 'Unknown error' }));
    throw new Error(`API Error: ${response.status} - ${errorBody.message}`);
  }

  // Handle successful response
  return response.json();
}

// 3. Params (Query Parameters): Example use in a Server Component
// The component is the 'client' calling your API wrapper
export async function getPosts(filters) {
    const searchParams = new URLSearchParams(filters).toString(); // { limit: 10, page: 1 } -> "limit=10&page=1"
    const endpoint = `/posts?${searchParams}`;
    
    return apiFetch(endpoint, {
        method: 'GET',
        // Example: Only revalidate every 60 seconds
        next: { revalidate: 60 } 
    });
}

// 4. Payload (Body) and Headers: Example use for a POST request
export async function createPost(postData, userToken) {
    // postData is the Payload/Body
    return apiFetch('/posts', {
        method: 'POST',
        body: postData, 
        // Example: Passing a specific header (Authorization in this case)
        token: userToken 
    });
}

 

 

// lib/api-client-axios.js
import axios from 'axios';

const api = axios.create({
    baseURL: process.env.API_BASE_URL,
    // 1. Headers: Default headers for ALL requests
    headers: {
        'Content-Type': 'application/json',
    },
});

// Production Best Practice: Using Interceptors for global error/auth handling
api.interceptors.request.use((config) => {
    // 1. Headers: Add Authorization header dynamically for every request
    const token = localStorage.getItem('token'); // NOTE: Use for Client Components only!
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
});

api.interceptors.response.use(
    (response) => response.data, // Axios automatically puts data in .data
    (error) => {
        // Production Grade Error Handling
        if (error.response) {
            console.error('Request failed:', error.response.data);
            throw new Error(error.response.data.message || 'Server error');
        } else {
            console.error('Network Error:', error.message);
            throw new Error('Network error or request timed out');
        }
    }
);

// 3. Params (Query Parameters): Example use
export async function getPosts(filters) {
    // Axios uses the `params` key in the config object
    return api.get('/posts', { 
        params: filters // filters: { limit: 10, page: 1 } -> /posts?limit=10&page=1
    });
}

// 4. Payload (Body) and Headers: Example use for a POST request
export async function createPost(postData, userToken) {
    // postData is the Payload/Body (first argument after the URL)
    return api.post('/posts', postData, {
        // Override or add a header for this specific request
        headers: {
            'Authorization': `Bearer ${userToken}`,
            'X-Custom-Header': 'NextJS-App'
        }
    });

Comments

Popular posts from this blog

CyberSecurity

VERTICAL SCALING 💋

prisma using in project idx 13.3