2

I want to add a middleware to all API calls with React RTK. To be specific I want to add the Firebase Performance Monitoring plugin to monitor the HTTP request: https://rnfirebase.io/perf/usage#http-request-tracing.

So how can I add a middleware just for the API calls?

This is our api (this is off course not the whole api but you get the poin):

export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({
    baseUrl: Config.API_ENDPOINT,
    prepareHeaders: (headers, { getState }) => {
      const token = (getState() as RootState).app.token 

      if (token) {
        headers.set('Authorization', 'Bearer ' + token)
      }

      return headers
    }
  }),
  tagTypes: ['AuthToken'],
  endpoints: (builder) => ({
    auth: builder.query<BaseResponse<AuthResult>, any>({
      query: () => ({
        url: '/auth/token',
        method: 'POST',
        responseHandler: (response) => response.json()
      }),
      providesTags: ['AuthToken'],
    }),
   }),
  }),
})

Thanks in advance.

Dirk
  • 3,095
  • 4
  • 19
  • 37

1 Answers1

0

To add a middleware specifically for API calls in React RTK, you can utilize the baseQuery option provided by createApi and customize it with your desired middleware.

In your code, you are using fetchBaseQuery as the base query for making API calls. To add the Firebase Performance Monitoring plugin as middleware, you can create a custom fetchBaseQuery function that wraps the original fetchBaseQuery and applies the monitoring plugin.

Add the following snippet to your code:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { initializeApp } from 'firebase/app'
import { getPerformance, trace } from 'firebase/performance'

// Initialize Firebase Performance Monitoring
const firebaseConfig = { /* Your Firebase config */ }
const app = initializeApp(firebaseConfig)
const perf = getPerformance(app)

// Custom fetchBaseQuery with middleware
const customFetchBaseQuery = ({ baseUrl, prepareHeaders }) => {
const baseQuery = fetchBaseQuery({
    baseUrl,
    prepareHeaders,
})
return async (args, api, extraOptions) => {
const { url } = args
const traceName = `HTTP ${args.method} ${url}`

// Start Firebase Performance Monitoring trace
const perfTrace = trace(perf, traceName)
perfTrace.start()

try {
  // Call the original fetchBaseQuery
  const result = await baseQuery(args, api, extraOptions)
  
  // Stop the trace on success
  perfTrace.stop()

  return result
} catch (error) {
  // Stop the trace on error
  perfTrace.stop()

  throw error
    }
  }
}
Ramc_26
  • 11
  • 2
  • Thanks. But how can I do this with TS types? Is it possible for customFetchBaseQuery to inherit fetchBaseQuery types? – Dirk Jun 02 '23 at 12:35
  • And how do I get the status code and response headers from `const response = await baseQuery(args, api, extraOptions)`? – Dirk Jun 02 '23 at 13:19