基于RTK Query代码生成创建可配置API调用库的可行性及实现方案咨询
基于RTK Query代码生成创建可配置API调用库的可行性及实现方案咨询
当然可以实现!你的思路非常合理,RTK Query早就考虑到了这种多项目复用、需要动态配置的场景,咱们只需要把生成的API定义和网络请求配置解耦,就能轻松实现这个可配置的API工厂函数。
下面我给你一步步拆解实现方案,附带具体的代码示例:
一、先调整生成的API代码,解耦endpoint和baseQuery
首先,我们要确保生成的API代码里,接口定义(endpoints)和网络请求配置(baseQuery)是分开的。如果用的是RTK Query的openapi代码生成工具,你可以在配置里开启自动导出endpoints函数,省得手动抽离:
1. 代码生成配置(可选但推荐)
在你的codegen.config.ts里添加exportEndpoints: true,这样生成的代码会自动把endpoints函数单独导出:
import type { CodegenConfig } from '@reduxjs/toolkit/query/codegen-openapi'; const config: CodegenConfig = { schemaPath: 'https://你的API文档地址/openapi.json', apiFile: './src/myApiBase.ts', apiImport: 'emptyApi', outputFile: './src/generatedMyApi.ts', exportEndpoints: true, // 关键配置:自动导出endpoints函数 reducerPath: 'myApi', hooks: true, }; export default config;
2. 生成后的基础API结构
生成的代码会类似这样,我们重点关注导出的myApiEndpoints(接口定义)和基础的myApi:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 自动导出的endpoints函数,包含所有生成的接口定义 export const myApiEndpoints = (builder) => ({ getUser: builder.query({ query: (id) => `/users/${id}`, }), createPost: builder.mutation({ query: (data) => ({ url: '/posts', method: 'POST', body: data, }), }), // ...其他生成的接口 }); // 基础API实例,用占位的baseQuery,后续会被替换 export const myApi = createApi({ reducerPath: 'myApi', baseQuery: fetchBaseQuery({ baseUrl: '' }), endpoints: myApiEndpoints, tagTypes: ['User', 'Post'], // 生成的缓存标签,要记得复用 });
二、实现你的createMyApi工厂函数
现在我们可以写一个工厂函数,接收baseUrl和getTokenFunction,动态创建带有自定义配置的API实例:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import { myApiEndpoints, myApi } from './generatedMyApi'; export const createMyApi = (baseUrl, getTokenFunction, reducerPath = myApi.reducerPath) => { // 1. 创建自定义的baseQuery,包含动态baseUrl和token逻辑 const customBaseQuery = fetchBaseQuery({ baseUrl, prepareHeaders: async (headers) => { // 支持同步/异步获取token,RTK Query会自动处理异步逻辑 const token = await getTokenFunction(); if (token) { headers.set('Authorization', `Bearer ${token}`); } return headers; }, // 还可以添加其他全局配置,比如超时、错误处理 timeout: 10000, }); // 2. 基于生成的endpoints,创建新的API实例 return createApi({ reducerPath, // 允许自定义reducerPath,避免多API实例冲突 baseQuery: customBaseQuery, endpoints: myApiEndpoints, // 复用所有生成的接口定义 tagTypes: myApi.tagTypes, // 复用缓存标签,保证缓存功能正常 }); };
三、在各个React项目中使用
每个项目只需要传入自己的baseUrl和getTokenFunction,就能得到适配自身的API实例:
项目A(使用API v1)
import { createMyApi } from '你的API库路径'; // 项目专属配置 const baseUrl = 'https://api.v1.yourdomain.com'; const getToken = () => localStorage.getItem('projectA_auth_token'); // 创建项目专属的API实例 export const api = createMyApi(baseUrl, getToken); // 直接用生成的hooks调用接口 export const { useGetUserQuery, useCreatePostMutation } = api;
项目B(使用API v2)
import { createMyApi } from '你的API库路径'; // 项目专属配置 const baseUrl = 'https://api.v2.yourdomain.com'; const getToken = async () => { // 比如从异步存储或接口获取token const res = await fetch('/api/get-token'); const data = await res.json(); return data.token; }; // 创建项目专属的API实例 export const api = createMyApi(baseUrl, getToken); // 同样使用生成的hooks export const { useGetUserQuery, useCreatePostMutation } = api;
四、几个关键注意事项
- 缓存标签(tagTypes)必须复用:如果生成的API有tagTypes,一定要在新创建的API里传入,否则缓存失效、自动刷新等功能会失效。
- 支持多API实例共存:如果同一个项目需要同时调用多个API版本,可以给每个实例传不同的
reducerPath,避免Redux store里的状态冲突。 - 灵活扩展配置:可以在
createMyApi里添加更多可选参数,比如自定义错误处理函数、额外的请求头,让库的适配性更强。 - 异步token的支持:代码里的
prepareHeaders支持异步逻辑,所以如果你的token需要从Promise获取(比如从异步存储、刷新接口),直接用await就行,RTK Query会自动处理。
这样一来,你就拥有了一个可以在多个React项目中复用的API调用库,每个项目都能根据自己的需求配置baseUrl和token逻辑,同时完全复用RTK Query代码生成的所有接口定义和hooks,非常方便!




