1.2.6 • Published 1 month ago

@tdio/io v1.2.6

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

@tdio/io

IO aka http for api request (based on axios)

Installation

yarn add @tdio/io -D

Features

  • Built on top of axios with enhanced functionality
  • Automatic API response normalization
  • Built-in error handling and status code management
  • Support for request/response interceptors
  • File upload support
  • JSONP support
  • Configurable API assertion
  • TypeScript support

Configuration

Default Configuration

const defaults = {
  // Base URL for all requests
  baseURL: '/api',
  
  // Request timeout in milliseconds
  timeout: 10000,
  
  // Default headers
  headers: {
    post: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  },
  
  // API response assertion
  asserter: ({ code }) => code == null || code === 0,
  
  // Response data transformation
  transform: (response) => {
    // Normalizes response data to { code, message, data } format
    // ...
  }
}

Setting Global Defaults

import { setDefaults } from '@tdio/io'

setDefaults({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'Authorization': 'Bearer token'
  }
})

Usage

Basic HTTP Requests

import { create } from '@tdio/io'

const http = create()

// GET request
const getData = async () => {
  const response = await http.get('/users')
  return response.data
}

// POST request
const createUser = async (userData) => {
  const response = await http.post('/users', userData)
  return response.data
}

// PUT request
const updateUser = async (id, userData) => {
  const response = await http.put(`/users/${id}`, userData)
  return response.data
}

// DELETE request
const deleteUser = async (id) => {
  const response = await http.delete(`/users/${id}`)
  return response.data
}

File Upload

const handleFileUpload = (event) => {
  // Get the selected file from the input
  const file = event.target.files[0]

  // Create a new FormData object and append the file to it
  const formData = new FormData()
  formData.append('testFile', file)

  // Make a POST request to the File Upload API with the FormData object
  http.put('foo/upload', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      'X-Requested-With': '@tdio/io',
      'X-RapidApi-Host': 'file-upload8.p.rapidapi.com',
    },
  })
}

API Factory

The API Factory provides a more structured and configurable way to create API instances compared to the base API. Here are the key differences and advantages:

import { ApiFactory, create } from '@tdio/io'

// Base API instance
const http = create({
  baseURL: 'https://api.example.com',
  timeout: 5000
})

// API Factory instance
const api = ApiFactory({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  // Additional factory-specific options
  urlResolver: (url, config) => {
    // Customize URL resolution
    return url.startsWith('/') ? url : `/${url}`
  },
  configReducer: (config) => {
    // Transform request config before sending
    return {
      ...config,
      headers: {
        ...config.headers,
        'X-Custom-Header': 'value'
      }
    }
  }
})

Key Features of API Factory

  1. Instance Management

    // Get the underlying axios instance
    const engine = api.getEnginer()
    
    // Update instance-specific defaults
    api.setDefaults({
      headers: {
        'Authorization': 'Bearer token'
      }
    })
  2. Automatic Response Normalization

    // API Factory automatically unwraps the response data
    const users = await api.get('/users')  // Returns data directly
    
    // Base API requires manual unwrapping
    const response = await http.get('/users')
    const users = response.data
  3. URL Resolution

    const api = ApiFactory({
      urlResolver: (url, config) => {
        // Add version prefix to all URLs
        return `/v1${url}`
      }
    })
    
    // URL will be automatically prefixed with /v1
    await api.get('users')  // Calls /v1/users
  4. Request Configuration

    const api = ApiFactory({
      configReducer: (config) => {
        // Add common headers or transform request config
        return {
          ...config,
          headers: {
            ...config.headers,
            'X-API-Key': process.env.API_KEY
          }
        }
      }
    })
  5. Type Safety

    // Type-safe API calls
    interface User {
      id: number;
      name: string;
    }
    
    const api = ApiFactory()
    
    // TypeScript will infer the return type
    const user = await api.get<User>('/users/1')

When to Use API Factory vs Base API

Use API Factory when you need:

  • Automatic response data unwrapping
  • Custom URL resolution logic
  • Request configuration transformation
  • Instance-specific configuration management
  • Type-safe API calls

Use Base API when you need:

  • Direct access to raw axios instance
  • Full control over response handling
  • Simpler setup with minimal configuration
  • Direct access to response metadata

Error Handling

try {
  const response = await http.get('/users')
  // Handle success
} catch (error) {
  // Error object includes:
  // - code: API error code
  // - message: Error message
  // - data: Response data
  // - config: Request configuration
  // - request: Request object
  // - response: Response object
  console.error(error.message)
}

Request/Response Interceptors

const http = create({
  onReq: (config) => {
    // Modify request config
    return config
  },
  onRes: (response) => {
    // Modify response
    return response
  },
  onErr: (error) => {
    // Handle error
    return error
  }
})

API Response Format

The package normalizes API responses to a standard format:

interface ApiResponse<T> {
  code: number | null;    // API status code
  message: string;        // Response message
  data: T;               // Response data
}

License

MIT Copyright (c) Tiduyun.com F2E Group

1.2.6

1 month ago