Blog>
Snippets

Customizing RTK Query API with createApi

Provide an example of customizing RTK Query's createApi for fetching data, including query definitions and the use of hook customizations.
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

// Define a service using a base URL and expected endpoints
export const apiService = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    getPosts: builder.query({
      query: () => 'posts'
    }),
    addPost: builder.mutation({
      query: (newPost) => ({
        url: 'posts',
        method: 'POST',
        body: newPost
      })
    })
  })
});

// Export hooks for usage in functional components which are automatically generated by createApi
export const { useGetPostsQuery, useAddPostMutation } = apiService;
This code snippet defines an API service using RTK Query's createApi function. It sets up a basic API with a 'getPosts' query and an 'addPost' mutation. It also exports the auto-generated hooks for these endpoints.
import { apiService } from './path-to-above-api-service';
import { configureStore } from '@reduxjs/toolkit';

export const store = configureStore({
  reducer: {
    // Add the generated reducer as a specific top-level slice
    [apiService.reducerPath]: apiService.reducer,
  },
  // Adding the api service middleware enables caching, invalidation, polling,
  // and other useful features of RTK Query
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(apiService.middleware),
});
This code integrates the 'apiService' defined above into a Redux store using configureStore from Redux Toolkit. The apiService reducer and middleware are included to handle data fetching and caching.
import { ApiProvider } from '@reduxjs/toolkit/query/react';
import { store } from './path-to-store';
import App from './App';

function MyApp() {
  return (
    <ApiProvider api={apiService} store={store}>
      <App />
    </ApiProvider>
  );
}
This code wraps the root component (App) with the ApiProvider from RTK Query, passing the store and apiService to make the RTK Query's hooks available throughout the application.
import { createApi } from '@reduxjs/toolkit/query/react';
import { firestore } from 'firebase/app'; // Import Firebase SDK

// Define a baseQuery using the queryFn from RTK Query
const firebaseBaseQuery = ({ queryFn }) => async (arg, api, extraOptions) => {
  try {
    // Execute the logic using Firebase SDK
    const data = await queryFn(arg, api, extraOptions);
    return { data };
  } catch (error) {
    return { error };
  }
};

// Custom API hook to interact with Firestore
export const firestoreApi = createApi({
  reducerPath: 'firestoreApi',
  baseQuery: firebaseBaseQuery,
  endpoints: (builder) => ({
    getScores: builder.query({
      queryFn: async () => ({
        data: await firestore.collection('scores').get()
      })
    })
    // ...additional endpoints...
  })
});

// Automatically generated hooks for the Firestore endpoints
export const { useGetScoresQuery } = firestoreApi;
This snippet demonstrates how to use createApi with Firebase Firestore by creating a custom baseQuery using queryFn. It accesses Firestore data using Firebase SDK within the query functions.