普通视图

发现新文章,点击刷新页面。
昨天以前首页

一个让你爽歪歪的请求工具是怎样的

作者 古韵
2025年12月10日 08:35

各位好,很久没出来发一发alova文章了,现在的alova已经更新到第3个大版本了,看这篇文章可能会让你对它有个全新的认识。

如果你之前了解过alova,那么大概率知道alova是一个轻量级的请求策略库,通过它的客户端请求hooks和缓存高效地处理前端数据请求。

而到今天,alova3在此基础上实现了更大的提升,它不只是在客户端中使用,现在还能在服务端环境下大放异彩,是一个全栈式的极致高效的请求工具集,其核心目标是帮助开发团队更高效地集成和调用API,并且完美兼容fetch、axios等HTTP客户端,以及react、vue、svelte等UI框架。

具体来说,alova3相比之前的版本,它带来了以下的大更新。

  1. 多级缓存:请求效率和减压利器。
  2. 全栈的请求策略:帮你大大减少请求代码。
  3. 更加现代化的OpenAPI工具:不仅可以自动生成请求代码,还能把api文档搬到编辑器中,交互式地调用api,打破过去的api集成流程。

这里我想郑重声明一下,由于ai大模型对alova知识学习的不足,现在网上充斥着各种ai编写的alova的错误使用的文章,建议大家前往alova官网了解alova的正确使用方法。

一、多级缓存

多级缓存机制可以为你的服务端应用提供最快的请求体验。你可以自由选择单级缓存还是多级缓存使用,它们运行机制如下:

graph TD
    A[用户请求] --> B{检查L1缓存}
    B -->|命中| C[返回数据]
    B -->|未命中| D{检查L2缓存}
    D -->|命中| E[更新L1缓存]
    D -->|未命中| F[请求API接口]
    F --> G[更新L2缓存]
    E --> C
    G --> E
    C --> H[结束]

默认情况下,alova 的一级缓存是简单的 object 以 key-value 的方式缓存,而二级缓存在不同环境下的默认表现也不同,具体看下面。

客户端

在客户端环境下,一级缓存一般用于短时的请求数据缓存,例如几分钟或几秒钟的频繁请求相同数据带来的性能消耗,当你在写 todo 详情页的时候,你可能会想到用户会频繁在 todo 列表中点击查看详情,此时使用一级缓存可以大大提升效率,降低服务端压力。

// 对详情数据设置60秒的一级缓存
alovaInstance.Get('/todo/detail', {
  params: {
    id: 'xxx'
  },
  cacheFor: 60 * 1000, // 设置60秒的一级缓存
  // ...
});

而二级缓存可用于一些枚举数据、节日等长期不变的请求为主,默认使用localStorage存储。

// 对枚举数据设置3天缓存时间
alovaInstance.Get('/config/enum', {
  params: {
    key: 'xxx'
  },
  cacheFor: {
    mode: 'restore',
    expire: 3 * 24 * 3600 * 1000 // 缓存3天时间
  }, 
});

服务端

在服务端环境下,多级缓存机制特别适用于以下场景:

  1. 高访问频率和低延迟需求:例如热门新闻、商品详情,可以进一步减少网络开销,在网络不稳定时也保持更快的响应。

  2. 减轻下游服务器压力:例如有访问高峰期的服务,上层缓存可以有效减少对后端数据库和微服务的压力。

  3. 整合多个下游服务器的数据合并和处理:多个串行请求可能导致更长的响应时间,也可能因复杂的数据转换消耗性能,可将转换后的数据进行缓存。

  4. API 速率限制和计费:天气预报服务 API 每小时更新一次天气信息,地理位置数据 API 等。

  5. 鉴权数据:用户token等数据缓存到内存中,避免频繁的鉴权操作。

  6. 请求速率限制等分布式数据:用户的请求次数限制等数据。

具体可以看这篇文章

以下是一个使用进程间内存共享适配器加 LRU cache 作为一级缓存,redis 作为二级缓存的示例:

const { createPSCAdapter, NodeSyncAdapter } = require('@alova/psc');
const { LRUCache } = require('lru-cache');
const RedisStorageAdapter = require('./adapter-redis');

function lRUCache(options = {}) {
  const cache = new LRUCache(options);
  return {
    set(key, value) {
      return cache.set(key, value);
    },

    get(key) {
      return cache.get(key);
    },

    remove(key) {
      return cache.delete(key);
    },

    clear() {
      return cache.clear();
    }
  };
}

const alovaInstance = createAlova({
  // ...

  // 进程间共享缓存适配器
  l1Cache: createPSCAdapter(
    NodeSyncAdapter(),
    lRUCache({
      max: 1000,
      ttl: 1000 * 60 * 10
    })
  ),

  // redis缓存适配器
  l2Cache: new RedisStorageAdapter({
    host: 'localhost',
    port: 6379,
    username: 'default',
    password: 'my-top-secret',
    db: 0
  })
});

通过多级缓存机制,alova3能够实现:

  • 响应时间减少80%+:通过内存缓存实现毫秒级响应
  • 服务器负载降低60%+:减少不必要的API调用
  • 离线体验优化:持久化缓存支持完整的离线功能
  • 带宽节约:减少重复数据传输

这种多级缓存架构使得alova3特别适合需要高性能数据访问的现代Web应用,在微服务架构和分布式系统中也表现出色。

二、全栈的请求策略

服务端请求策略

alova3一个关键特性是引入了对服务端的完整支持,你不仅可以在nodejs、deno、bun等运行时中使用,还提供了独有的服务端请求策略,简称server hooks,它可以很方便地处理分布式的BFF、API网关、第三方token管理等,同时还有请求速率限制、请求重试、验证码发送与校验等模块,可以快速实现分布式的特定业务逻辑。

BFF、API网关、第三方token管理等,在这篇文章中有详细的介绍,这边我们来看看验证码发送校验模块的使用。

按照惯例,首先创建一个alova实例。

const { createAlova } = require('alova/server');
const RedisStorageAdapter = require('@alova/storage-redis');
const adapterFetch = require('alova/fetch');

export const alovaInstance = createAlova({
  // ...
  requestAdapter: adapterFetch(),
  // redis缓存适配器
  l2Cache: new RedisStorageAdapter({
    host: 'localhost',
    port: 6379,
    username: 'default',
    password: 'my-top-secret',
    db: 0
  })
});

然后再创建一个验证码提供者函数,并指定使用redis适配器作为缓存载体,以便实现分布式环境下的使用。

const { createCaptchaProvider } = require('alova/server');

const { sendCaptcha, verifyCaptcha } = createCaptchaProvider({
  store: alovaInstance.options.l2Cache
});

export sendCaptcha;
export verifyCaptcha;

第三步,再发送验证码,这里我们使用retry来实现重试,提高成功率。

// 创建一个发送验证码的method实例
const createCaptchaMethod = (code, key) = > alovaInstance.Post('/api/captcha', {
  code,
  email: key,
});

// 使用sendCaptcha hook包装createCaptchaMethod
const captchaMethod = sendCaptcha(createCaptchaMethod, {
  key: 'xxx@xxx.com'
});

// 使用retry hook包装captchaMethod,并通过await发送请求并获取响应结果
const result = await retry(captchaMethod, {
  retry: 3,
  backoff: {
    delay: 2000
  }
});

最后一步,通过用户的提交来验证验证码。

const fakeCaptchaFromUserInput = '1234';
const isValid = await verifyCaptcha(fakeCaptchaFromUserInput, key);
console.log(isValid ? '验证通过' : '验证码错误');

客户端的请求策略

alova3的客户端请求策略与之前的版本大相径庭,依然提供了useRequestuseWatcherusePagination等UI框架相关的hooks,在这里大家应该都很熟悉了,但不同的是,无论你使用react、vue还是svelte,这些hook都由统一的alova/client中导入。

import { useRequest } from 'alova/client';

const { data, loading, error, send } = useRequest(alovaInstance.Get('/todo/list'));

全栈框架nuxt支持

虽然在之前的版本中,alova已经支持在next、nuxt、svelitekit等SSR框架中使用,不过在alova3中,提供了一个专门适配nuxt的statesHook,可以在使用useRequestuseWatcher等几乎所有的hooks时不仅可以同步两端的数据,像内置的useFetch一样避免在客户端重复请求,还可以同步例如DateError等以及自定义类型的数据,用法也非常简单,设置一下NuxtHook即可。

import { createAlova } from 'alova';
import NuxtHook from 'alova/nuxt';

export const alovaInstance = createAlova({
  // ...
  statesHook: NuxtHook({
    nuxtApp: useNuxtApp // 必须指定useNuxtApp
  })
});

三、工具链支持:更加现代化的OpenAPI工具

除了核心库的增强,alova3还提供了开发工具和vscode扩展来优化工作流。

如果你的项目支持openapi,这些开发工具可以基本消除API文档,让你直接在编辑器中查找接口、查看完整文档并交互式地快速插入接口的调用代码,很大程度地提升了开发效率和体验。

同时,你还可以完全控制openapi在前端生成的内容,例如过滤掉某些接口,新增、删除或修改某个接口的参数等,这些在openapi文件不够规范,或者有错误时非常有用,并且是其他openapi自动生成工具所不具备的。

一起来具体看看怎么回事。

快速查找和插入调用代码

自定义修改生成内容

在一般情况下,服务端的返回数据格式会外包一层,例如:

{
  code: 0,
  message: "success",
  data: {
    // ...
  }
}

而此时我们希望生成的响应数据类型为response.data,你可以在alova配置文件中使用payloadModifier插件。

import { defineConfig } from '@alova/wormhole';
import { payloadModifier } from '@alova/wormhole/plugin';

export default defineConfig({
  generator: [
    {
      // ...
      plugin: [
        payloadModifier([
          {
            scope: 'response',
            handler: schema => schema.data
          }
        ])
      ]
    }
  ]
});

你也还可以通过handleApi实现完全的自定义,例如以下是一个修改tag的例子:

export default defineConfig({
  generator: [
    {
      handleApi: apiDescription => {
        if (apiDescription.url.includes('/user')) {
          apiDescription.tags = ['userTag'];
        }
        return apiDescription;
      }
    }
  ]
});

边查边接入接口

使用alova的vscode扩展,你可以直接在编辑器中查找接口,并直接插入调用代码,不仅如此,接口的所有相关信息都可以直接在代码中查看,像这样。

image.png

弹框中能清楚的看到接口的描述信息、请求参数、响应参数等,你可以一边看着弹框中的参数,一边在代码中传参,这个点子太棒啦,再也不用在api文档和编辑器中来回切换,然后每次还要重新找对应信息了。

编辑器中的api文档

这个vscode扩展还提供了在编辑器中查看接口文档的功能,你可以直接在编辑的侧边栏中查看接口文档,就像这样。

也可以在代码中的调用代码上直接点击“view documentation”打开对应的接口文档,可以实现快速查看接口的描述信息、请求参数、响应参数等。

写在最后

到这里,你应该感受到了一点alova3的不同了吧,通过以上的方式让前端在接口集成方向很大程度地提升效率,无论你是前端开发者希望提升应用性能,还是后端工程师需要构建高效的API网关,亦或是全栈开发者追求统一的开发体验,alova3都能为你提供完整的支持。

如果觉得alova还不错,真诚希望你可以尝试体验一下,也可以给我们来一个免费的github stars

访问alovajs的官网查看更多详细信息:alovajs官网

有兴趣可以加入我们的交流社区,在第一时间获取到最新进展,也能直接和开发团队交流,提出你的想法和建议。

有任何问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。

如何从Axios平滑迁移到Alova

作者 古韵
2025年12月11日 11:59

Alova 是谁?

Alova 是一个请求工具集,它可以配合axios、fetch等请求工具实现高效的接口集成,是用来优化接口集成体验的。此外,它还能提供一些 Axios 不具备的便利功能,比如:

  • 内置缓存机制:不用自己操心数据缓存,Alova 能帮你自动管理,提升性能。
  • 请求策略灵活:可以根据不同场景设置不同的请求逻辑,比如强制刷新、依赖请求等。
  • 多框架支持:无论是 Vue、React 还是 Svelte、Solid,Alova 都能很好地集成。
  • 状态管理集成:请求的数据可以直接与组件状态关联,减少冗余代码。
  • 强大的适配器系统:支持自定义适配器,比如我们这次要讲的 —— 用 Alova 来兼容你现有的 Axios 实例!

简单来说,Alova 在保留类似 Axios 易用性的基础上,还提供了更多开箱即用的高级功能请移步到alova官方文档查看。

为什么要从 Axios 迁移到 Alova?

你可能会问:“Axios 用得好好的,为什么要迁?” 其实,迁移不一定是“非换不可”,而是一种“锦上添花”的选择。以下是一些常见的迁移动机:

  1. 希望简化复杂请求逻辑的管理:比如依赖请求、串并行控制、自动重试等,Alova 提供了更优雅的解决方案。
  2. 想要内置缓存,减少重复请求:如果你的应用有很多重复请求,Alova 的缓存机制可以显著提升性能。
  3. 多框架适配更方便:如果你在多个项目中使用不同框架,Alova 能提供一致的体验。
  4. 想逐步优化现有项目:不想大动干戈重写代码,但又想引入更现代的请求管理方式。

如果你有以上需求,那 Alova 就非常值得尝试!

从 Axios 迁移到 Alova,到底难不难?

Alova 官方提供了非常友好的 Axios 迁移方案,核心就一个字:稳。

官方迁移指南的设计理念是:

  • 最小改动:你不需要一下子重写所有代码,只需引入 Alova,然后逐步迁移。
  • 渐进迁移:一个接口一个接口地改,节奏由你掌控。
  • 保持一致性:你现有的 Axios 实例、配置、拦截器,统统都能继续用!
  • 新老共存:迁移期间,Axios 和 Alova 可以同时运行,互不干扰。

是不是听起来就很贴心?接下来,我们就来看看具体怎么操作。

从 Axios 迁移到 Alova 的具体步骤

第一步:安装 Alova 和 Axios 适配器

首先,你需要通过包管理工具安装 Alova 以及它的 Axios 适配器。

# 如果你用 npm
npm install alova @alova/adapter-axios

# 或者用 yarn
yarn add alova @alova/adapter-axios

# 或者用 pnpm
pnpm install alova @alova/adapter-axios

第二步:创建 Alova 实例,并传入你的 Axios 实例

这一步是关键,你可以直接复用你现有的 Axios 实例!

import { createAlova } from 'alova';
import { axiosRequestAdapter } from '@alova/adapter-axios';
import axiosInstance from './your-axios-instance'; // 你原来就有的 axios 实例

const alovaInst = createAlova({
  statesHook, // 这里填你项目里用的 Hook,比如 VueHook / ReactHook / SvelteHook
  requestAdapter: axiosRequestAdapter({
    axios: axiosInstance // 把你原来的 axios 实例传进去
  })
});

你啥都不用改,原来的 axios 实例、拦截器、配置全都有效!

第三步:继续使用原有 Axios 代码,不用急着改

没错,哪怕你刚刚创建了 Alova 实例,你原来的 Axios 代码照样跑得好好的!你可以慢慢来,不用急着一口气全改完。

比如这样:

const getUser = id => axios.get(`/user/${id}`); // 你原来的写法,依旧能用

当然,你也可以开始尝鲜,用 Alova 的方式发起请求:

const getUser = id => alovaInst.Get(`/user/${id}`);

// 在组件里使用(以 React 为例)
const { loading, data, error } = useRequest(getUser(userId));

第四步:逐步把 Axios 请求改写为 Alova 请求

等你熟悉了 Alova,就可以开始把原来的 axios.getaxios.post 等方法,逐步替换为 Alova 的 alovaInst.GetalovaInst.Post,非常简单:

原来的写法:

const todoList = id => axios.get('/todo');

改写为 Alova 写法:

const todoList = id => alovaInst.Get('/todo');

带参数的 POST 请求:

// 原来的写法
const submitTodo = data =>
  axios.post('/todo', data, {
    responseType: 'json',
    responseEncoding: 'utf8'
  });

// Alova 写法
const submitTodo = data =>
  alovaInst.Post('/todo', data, {
    responseType: 'json',
    responseEncoding: 'utf8'
  });

看,参数基本都能直接对应过去,写法也类似,学习成本极低!

最后

从 Axios 迁移到 Alova,其实并没有想象中那么难,甚至可以说非常平滑,尤其是对老项目的兼容性做得非常友好。

所以,如果你:

  • 已经在使用 Axios,但想尝试更现代的请求管理方式;
  • 希望引入缓存、优化请求策略、提升应用性能;
  • 想逐步优化代码,又不想一夜之间重写所有逻辑;

不妨试试 Alova,按照这个迁移指南可以轻松上手。

如果觉得alova还不错,真诚希望你可以尝试体验一下,也可以给我们来一个免费的github stars

访问alovajs的官网查看更多详细信息:alovajs官网

有兴趣可以加入我们的交流社区,在第一时间获取到最新进展,也能直接和开发团队交流,提出你的想法和建议。

❌
❌