Wretch 开源项目使用教程:现代化 Fetch 封装库的完整指南

Wretch 开源项目使用教程:现代化 Fetch 封装库的完整指南

【免费下载链接】wretch A tiny wrapper built around fetch with an intuitive syntax. :candy: 【免费下载链接】wretch 项目地址: https://gitcode.com/gh_mirrors/wr/wretch

前言:为什么需要 Wretch?

在现代 Web 开发中,fetch API 已经成为浏览器原生网络请求的标准。然而,原生 fetch 在使用过程中存在一些痛点:

  • ❌ 需要手动处理响应解析(.json(), .text()
  • ❌ HTTP 错误状态码不会自动抛出异常
  • ❌ JSON 序列化需要手动设置 headers 和 body
  • ❌ 缺乏请求重试、缓存等高级功能
  • ❌ 配置重复代码较多

Wretch 正是为了解决这些问题而生的轻量级封装库,它提供了直观的链式 API 和丰富的功能扩展。

Wretch 核心特性一览

特性描述优势
🪶 轻量级核心仅 2KB gzip几乎无性能开销
💡 直观语法链式调用设计代码更易读易写
🧊 不可变设计每次调用返回新实例安全的重用机制
🔌 模块化扩展插件和中间件系统按需加载功能
🧩 多平台支持浏览器、Node.js、Deno一致的开发体验
🦺 TypeScript完整的类型定义开发时类型安全

快速开始

安装 Wretch

# 使用 npm
npm install wretch

# 使用 yarn
yarn add wretch

# 使用 pnpm
pnpm add wretch

基础使用示例

import wretch from 'wretch'

// 最简单的 GET 请求
wretch('https://api.example.com/data')
  .get()
  .json(data => {
    console.log('获取到的数据:', data)
  })
  .catch(error => {
    console.error('请求失败:', error)
  })

// 带错误处理的 POST 请求
wretch('https://api.example.com/users')
  .post({ name: '张三', age: 25 })
  .json(response => {
    console.log('用户创建成功:', response)
  })
  .badRequest(error => {
    console.error('请求参数错误:', error)
  })
  .unauthorized(error => {
    console.error('未授权访问:', error)
  })

核心功能详解

1. 请求链式操作

Wretch 采用清晰的链式调用设计:

mermaid

2. 自动错误处理

与传统 fetch 对比:

// 原生 fetch 的错误处理
fetch('/api/data')
  .then(response => {
    if (!response.ok) {
      if (response.status === 404) throw new Error('Not found')
      else if (response.status === 401) throw new Error('Unauthorized')
      // ... 更多状态码判断
    }
    return response.json()
  })
  .then(data => console.log(data))
  .catch(error => console.error(error))

// Wretch 的错误处理
wretch('/api/data')
  .get()
  .notFound(error => console.error('404错误'))
  .unauthorized(error => console.error('401错误'))
  .error(500, error => console.error('服务器错误'))
  .json(data => console.log(data))

3. 智能 JSON 处理

Wretch 自动处理 JSON 序列化:

// 自动设置 Content-Type 为 application/json
wretch('/api/users')
  .post({ name: '李四', email: 'lisi@example.com' })
  .json(response => console.log(response))

// 等价于原生 fetch
fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: '李四', email: 'lisi@example.com' })
})

高级功能:Addons 插件系统

QueryString Addon

import QueryStringAddon from 'wretch/addons/queryString'

const api = wretch('https://api.example.com')
  .addon(QueryStringAddon)

// 构建查询参数
api.query({ page: 1, limit: 20, sort: 'name' })
  .get('/users')
  .json(users => console.log(users))

// 输出 URL: https://api.example.com/users?page=1&limit=20&sort=name

FormData Addon

import FormDataAddon from 'wretch/addons/formData'

const formData = {
  username: 'john_doe',
  avatar: fileInput.files[0], // 文件对象
  profile: {
    age: 30,
    hobbies: ['reading', 'swimming']
  }
}

wretch('/api/upload')
  .addon(FormDataAddon)
  .formData(formData)
  .post()
  .json(response => console.log('上传成功'))

完整的 Addons 功能对比表

Addon 名称功能描述使用场景
QueryString查询参数构建API 分页、过滤、排序
FormData多部分表单数据文件上传、复杂表单
FormUrlURL 编码表单传统表单提交
Abort请求取消超时控制、用户取消
BasicAuth基础认证简单的 API 认证
Progress进度监控大文件上传下载
Perfs性能监控请求性能分析

Middlewares 中间件系统

重试中间件 (Retry)

import { retry } from 'wretch/middlewares'

const resilientAPI = wretch('https://api.example.com')
  .middlewares([
    retry({
      delayTimer: 1000, // 初始延迟1秒
      delayRamp: (delay, attempts) => delay * attempts, // 指数退避
      maxAttempts: 5, // 最多重试5次
      until: (response, error) => {
        // 只在服务器错误时重试
        return response && response.status < 500
      },
      onRetry: ({ response, url, options }) => {
        console.log(`重试请求: ${url}, 尝试次数: ${options.retryCount}`)
      }
    })
  ])

// 使用带重试的API
resilientAPI.get('/unstable-endpoint')
  .json(data => console.log('最终成功:', data))

去重中间件 (Dedupe)

import { dedupe } from 'wretch/middlewares'

const dedupeAPI = wretch('https://api.example.com')
  .middlewares([
    dedupe({
      // 只对GET请求去重
      skip: (url, opts) => opts.method !== 'GET',
      // 自定义缓存键
      key: (url, opts) => `${opts.method}@${url}@${JSON.stringify(opts.headers)}`
    })
  ])

// 多个相同请求只会实际发送一个
dedupeAPI.get('/data').json(console.log)
dedupeAPI.get('/data').json(console.log) // 使用缓存结果

缓存中间件 (Throttling Cache)

import { throttlingCache } from 'wretch/middlewares'

const cachedAPI = wretch('https://api.example.com')
  .middlewares([
    throttlingCache({
      throttle: 30000, // 缓存30秒
      condition: response => response.ok, // 只缓存成功响应
      key: (url, opts) => `${opts.method}@${url}`
    })
  ])

// 30秒内的相同请求会返回缓存结果
cachedAPI.get('/user-profile')
  .json(profile => console.log('用户配置:', profile))

实战案例:构建完整的 API 客户端

1. 基础 API 客户端

// apiClient.js
import wretch from 'wretch'
import { retry, dedupe } from 'wretch/middlewares'
import QueryStringAddon from 'wretch/addons/queryString'

class APIClient {
  constructor(baseURL, options = {}) {
    this.client = wretch(baseURL)
      .addon(QueryStringAddon)
      .middlewares([
        retry({ maxAttempts: 3, delayTimer: 1000 }),
        dedupe()
      ])
      .errorType('json')
      .resolve(r => r.json())
    
    this.options = options
  }

  // 用户管理
  async getUsers(params = {}) {
    return this.client
      .query(params)
      .get('/users')
      .catch(error => this.handleError(error, '获取用户列表失败'))
  }

  async createUser(userData) {
    return this.client
      .post(userData)
      .url('/users')
      .catch(error => this.handleError(error, '创建用户失败'))
  }

  // 错误处理
  handleError(error, defaultMessage) {
    if (error.json) {
      throw new Error(error.json.message || defaultMessage)
    }
    throw new Error(defaultMessage)
  }
}

// 使用示例
const api = new APIClient('https://api.example.com')

// 获取用户列表
const users = await api.getUsers({ page: 1, limit: 20 })

// 创建新用户
const newUser = await api.createUser({
  name: '王五',
  email: 'wangwu@example.com',
  role: 'user'
})

2. 带认证的 API 客户端

// authApiClient.js
import wretch from 'wretch'
import { retry } from 'wretch/middlewares'
import BasicAuthAddon from 'wretch/addons/basicAuth'

class AuthAPIClient {
  constructor(baseURL) {
    this.baseClient = wretch(baseURL)
      .addon(BasicAuthAddon)
      .middlewares([retry({ maxAttempts: 2 })])
      .errorType('json')
    
    this.token = null
  }

  setToken(token) {
    this.token = token
    return this
  }

  get client() {
    let client = this.baseClient
    if (this.token) {
      client = client.auth(`Bearer ${this.token}`)
    }
    return client
  }

  async login(credentials) {
    const response = await this.client
      .post(credentials)
      .url('/auth/login')
      .json()
    
    this.setToken(response.token)
    return response
  }

  async getProtectedData() {
    return this.client
      .get('/protected/data')
      .unauthorized(async (error, originalRequest) => {
        // Token 过期,尝试刷新
        const newToken = await this.refreshToken()
        this.setToken(newToken)
        // 重试原始请求
        return originalRequest.auth(`Bearer ${newToken}`).get().json()
      })
      .json()
  }

  async refreshToken() {
    // 实现token刷新逻辑
    const response = await this.client
      .post({ refreshToken: this.refreshToken })
      .url('/auth/refresh')
      .json()
    return response.token
  }
}

性能优化最佳实践

1. 请求合并与缓存策略

// 使用去重和缓存中间件
const optimizedAPI = wretch('https://api.example.com')
  .middlewares([
    dedupe(), // 避免重复请求
    throttlingCache({ throttle: 60000 }) // 缓存1分钟
  ])

// 配置全局默认选项
wretch.options({
  mode: 'cors',
  credentials: 'include',
  cache: 'default'
})

2. 错误处理优化

// 统一的错误处理封装
function createAPIWithErrorHandling(baseURL) {
  return wretch(baseURL)
    .errorType('json')
    .catcher(404, error => {
      console.error('资源不存在:', error)
      throw new Error('请求的资源不存在')
    })
    .catcher(500, error => {
      console.error('服务器错误:', error)
      throw new Error('服务器内部错误,请稍后重试')
    })
    .catcherFallback(error => {
      console.error('未知错误:', error)
      throw new Error('网络请求失败')
    })
}

常见问题解答 (FAQ)

Q1: Wretch 和 axios 有什么区别?

特性WretchAxios
大小~2KB gzip~4KB gzip
依赖无依赖需要 http adapter
语法链式调用,更简洁配置对象形式
Tree Shaking支持按需导入全部导入
原生支持基于 fetch API基于 XMLHttpRequest

Q2: 如何在 Node.js 中使用 Wretch?

import wretch from 'wretch'
import fetch from 'node-fetch'
import { FormData } from 'node-fetch'

// 提供必要的 polyfills
wretch.polyfills({
  fetch,
  FormData
})

// 现在可以正常使用
const data = await wretch('https://api.example.com')
  .get()
  .json()

Q3: 如何处理文件上传?

import FormDataAddon from 'wretch/addons/formData'

const formData = {
  file: fileObject,
  metadata: JSON.stringify({ description: '项目文档' })
}

wretch('/api/upload')
  .addon(FormDataAddon)
  .formData(formData)
  .post()
  .json(response => console.log('上传成功:', response))

总结

Wretch 作为一个轻量级的 fetch 封装库,提供了现代化、直观的 API 设计,极大地简化了网络请求的处理。通过其模块化的插件系统和中间件机制,开发者可以按需扩展功能,保持代码的简洁性和可维护性。

主要优势:

  • ✅ 极小的体积开销
  • ✅ 直观的链式调用语法
  • ✅ 强大的错误处理机制
  • ✅ 丰富的插件生态系统
  • ✅ 优秀的 TypeScript 支持

无论是简单的数据获取还是复杂的 API 客户端构建,Wretch 都能提供优雅的解决方案。建议在实际项目中尝试使用,体验其带来的开发效率提升。

下一步学习建议:

  1. 阅读官方文档深入了解每个 API 的细节
  2. 尝试编写自定义中间件来解决特定业务需求
  3. 探索更多的 addons 来扩展 Wretch 的功能
  4. 在项目中逐步替换现有的请求库,体验改进效果

【免费下载链接】wretch A tiny wrapper built around fetch with an intuitive syntax. :candy: 【免费下载链接】wretch 项目地址: https://gitcode.com/gh_mirrors/wr/wretch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值