You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RTK Query中使用不同baseQuery?我认为应用只能有一个createApi

在RTK Query中使用多种baseQuery的两种方案

你之前的理解有误——RTK Query完全支持创建多个createApi实例,也可以在同一个实例里动态切换不同的baseQuery。下面给你两种可行的实现方式:

方案一:创建多个独立的API切片

如果你的REST API和GraphQL API是完全独立的业务模块,直接分开创建两个createApi实例是最简单的方案,各自使用对应的baseQuery,最后都注册到Redux Store即可。

步骤1:分别定义两个API切片

保留你原来的两个代码示例,作为独立的切片:

// restApiSlice.js
export const restApiSlice = createApi({
 reducerPath: "restApiSlice",
 baseQuery: axiosBaseQuery,
 endpoints: (builder) => ({
   fetchSomething: builder.query<Resource, string>({
     query: (resourceUUID) => ({
       url: `/services/buresource/collections/${resourceUUID}?component_level=1`,
       method: "get",
      }),
    }),
  }),
});

// graphqlApiSlice.js
export const graphqlApiSlice = createApi({
  reducerPath: "graphqlApiSlice",
  baseQuery: graphqlBaseQuery({
    baseUrl: 'https://graphqlzero.almansi.me/api',
  }),
  endpoints: (builder) => ({
    getPosts: builder.query({
      query: () => ({
        body: gql`
          query {
            posts {
              data {
                id
                title
              }
            }
          }
        `,
      }),
      transformResponse: (response) => response.posts.data,
    }),
  }),
})

步骤2:注册到Redux Store

在配置Store时,把两个切片的reducer和middleware都加进去:

import { configureStore } from '@reduxjs/toolkit';
import { restApiSlice } from './restApiSlice';
import { graphqlApiSlice } from './graphqlApiSlice';

export const store = configureStore({
  reducer: {
    [restApiSlice.reducerPath]: restApiSlice.reducer,
    [graphqlApiSlice.reducerPath]: graphqlApiSlice.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware()
      .concat(restApiSlice.middleware)
      .concat(graphqlApiSlice.middleware),
});

使用方式

在组件里分别导入两个切片生成的hooks即可:

import { useFetchSomethingQuery } from './restApiSlice';
import { useGetPostsQuery } from './graphqlApiSlice';

function MyComponent() {
  const { data: restData } = useFetchSomethingQuery('some-uuid');
  const { data: graphqlData } = useGetPostsQuery();
  
  // 渲染数据...
}

方案二:在同一个API切片中动态切换baseQuery

如果希望把所有接口放在同一个切片里,可以自定义一个复合baseQuery,根据每个endpoint的配置来选择使用axios还是graphql的baseQuery。

实现复合baseQuery

import { createApi, BaseQueryFn } from '@reduxjs/toolkit/query/react';
import axiosBaseQuery from './axiosBaseQuery';
import graphqlBaseQuery from './graphqlBaseQuery';

// 定义自定义查询参数类型,标记使用哪种baseQuery
type CustomQueryArgs = 
  | { type: 'rest'; url: string; method: string; [key: string]: any }
  | { type: 'graphql'; body: any; [key: string]: any };

const customBaseQuery: BaseQueryFn<CustomQueryArgs, unknown, unknown> = async (args, api, extraOptions) => {
  if (args.type === 'rest') {
    // 调用axios的baseQuery,移除type标记
    const { type, ...restArgs } = args;
    return axiosBaseQuery(restArgs, api, extraOptions);
  } else if (args.type === 'graphql') {
    // 调用graphql的baseQuery,移除type标记
    const { type, ...restArgs } = args;
    return graphqlBaseQuery({ baseUrl: 'https://graphqlzero.almansi.me/api' })(restArgs, api, extraOptions);
  }
  throw new Error('Unknown query type');
};

创建统一的API切片

export const unifiedApiSlice = createApi({
  reducerPath: "unifiedApiSlice",
  baseQuery: customBaseQuery,
  endpoints: (builder) => ({
    // REST接口,标记type为rest
    fetchSomething: builder.query<Resource, string>({
      query: (resourceUUID) => ({
        type: 'rest',
        url: `/services/buresource/collections/${resourceUUID}?component_level=1`,
        method: "get",
      }),
    }),
    // GraphQL接口,标记type为graphql
    getPosts: builder.query({
      query: () => ({
        type: 'graphql',
        body: gql`
          query {
            posts {
              data {
                id
                title
              }
            }
          }
        `,
      }),
      transformResponse: (response) => response.posts.data,
    }),
  }),
});

使用方式

直接导入统一切片的hooks即可:

import { useFetchSomethingQuery, useGetPostsQuery } from './unifiedApiSlice';

function MyComponent() {
  const { data: restData } = useFetchSomethingQuery('some-uuid');
  const { data: graphqlData } = useGetPostsQuery();
  
  // 渲染数据...
}

两种方案的选择建议

  • 如果两个API的业务逻辑完全独立,**方案一(多个切片)**更清晰,维护成本更低。
  • 如果需要在不同接口之间共享缓存状态或依赖关系,**方案二(统一切片)**更合适。

内容的提问来源于stack exchange,提问作者Zim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:01:11