Now.js Framework Documentation

Now.js Framework Documentation

ApiService

EN 29 Dec 2025 14:24

ApiService

Overview

ApiService is the HTTP request management system in Now.js Framework. It supports REST API calls, caching, and error handling.

When to use:

  • Need to make API calls
  • Need REST operations (GET, POST, PUT, DELETE)
  • Need request caching
  • Need automatic retry

Why use it:

  • ✅ Simple REST API interface
  • ✅ Automatic JSON handling
  • ✅ Request/Response interceptors
  • ✅ Caching support
  • ✅ Error normalization
  • ✅ Auth token integration

Basic Usage

GET Request

const response = await ApiService.get('/api/users');
console.log(response.data);

POST Request

const user = await ApiService.post('/api/users', {
  name: 'John',
  email: 'john@example.com'
});

PUT Request

await ApiService.put('/api/users/1', {
  name: 'John Updated'
});

DELETE Request

await ApiService.delete('/api/users/1');

Configuration

ApiService.init({
  baseUrl: '/api/v1',

  timeout: 30000,  // 30 seconds

  headers: {
    'Content-Type': 'application/json'
  },

  cache: {
    enabled: true,
    ttl: 300000  // 5 minutes
  }
});

API Reference

ApiService.get(url, options?)

GET request

Parameter Type Description
url string Endpoint URL
options.params object Query parameters
options.cache boolean Enable caching

Returns: Promise<Object>

const users = await ApiService.get('/users', {
  params: { page: 1, limit: 10 }
});
// GET /users?page=1&limit=10

ApiService.post(url, data, options?)

POST request

Parameter Type Description
url string Endpoint URL
data object Request body

Returns: Promise<Object>

ApiService.put(url, data, options?)

PUT request (full replace)

ApiService.patch(url, data, options?)

PATCH request (partial update)

ApiService.delete(url, options?)

DELETE request

ApiService.upload(url, file, options?)

File upload

Parameter Type Description
url string Upload endpoint
file File/FormData File to upload
options.onProgress function Progress callback
await ApiService.upload('/upload', file, {
  onProgress: (percent) => {
    console.log(`Upload: ${percent}%`);
  }
});

ApiService.clearCache(pattern?)

Clear cached responses

Parameter Type Description
pattern string/RegExp URL pattern to clear
// Clear all
ApiService.clearCache();

// Clear specific
ApiService.clearCache('/users');

Request Options

ApiService.get('/api/data', {
  // Query parameters
  params: { q: 'search' },

  // Custom headers
  headers: {
    'X-Custom-Header': 'value'
  },

  // Timeout override
  timeout: 60000,

  // Cache this request
  cache: true,

  // Cache TTL override
  cacheTtl: 600000,

  // Skip interceptors
  skipInterceptors: false
});

Interceptors

// Request interceptor
ApiService.interceptors.request.use((config) => {
  // Add auth header
  config.headers['Authorization'] = `Bearer ${getToken()}`;
  return config;
});

// Response interceptor
ApiService.interceptors.response.use(
  (response) => {
    // Transform response
    return response;
  },
  (error) => {
    // Handle errors
    if (error.status === 401) {
      AuthManager.requireAuth();
    }
    throw error;
  }
);

Error Handling

try {
  const data = await ApiService.get('/api/resource');
} catch (error) {
  // error.status - HTTP status code
  // error.message - Error message
  // error.data - Response body

  if (error.status === 404) {
    console.log('No data available');
  } else if (error.status === 422) {
    console.log('Validation errors:', error.data.errors);
  } else {
    console.log('Error:', error.message);
  }
}

Real-World Examples

CRUD Operations

// Create
const newUser = await ApiService.post('/users', {
  name: 'John',
  email: 'john@example.com'
});

// Read
const user = await ApiService.get(`/users/${newUser.id}`);

// Update
await ApiService.put(`/users/${user.id}`, {
  ...user,
  name: 'John Updated'
});

// Delete
await ApiService.delete(`/users/${user.id}`);

Search with Debounce

let searchTimeout;

function handleSearch(query) {
  clearTimeout(searchTimeout);

  searchTimeout = setTimeout(async () => {
    const results = await ApiService.get('/search', {
      params: { q: query }
    });
    displayResults(results.data);
  }, 300);
}

Paginated List

async function loadUsers(page = 1) {
  const response = await ApiService.get('/users', {
    params: {
      page,
      per_page: 20,
      sort: 'created_at',
      order: 'desc'
    }
  });

  return {
    users: response.data,
    total: response.meta.total,
    lastPage: response.meta.last_page
  };
}

File Upload with Progress

const input = document.getElementById('file-input');

input.onchange = async (e) => {
  const file = e.target.files[0];

  const progressBar = document.getElementById('progress');

  try {
    const result = await ApiService.upload('/upload', file, {
      onProgress: (percent) => {
        progressBar.style.width = `${percent}%`;
      }
    });

    NotificationManager.success('Upload complete!');
    console.log('File URL:', result.url);
  } catch (error) {
    NotificationManager.error('Upload failed');
  }
};

Common Pitfalls

⚠️ 1. Error Handling

// ❌ Not handling errors
const data = await ApiService.get('/api/data');

// ✅ Handle errors
try {
  const data = await ApiService.get('/api/data');
} catch (error) {
  NotificationManager.error(error.message);
}

⚠️ 2. Base URL

// ❌ Hardcode full URL
ApiService.get('https://api.example.com/users');

// ✅ Use relative path
ApiService.get('/users');