skip to Main Content

I’m working with microservices in a React app using Redux Toolkit (RTK) Query. I have two separate APIs:

Service A: For posting data (postData).

Service B: For fetching data (getData).

After performing a POST request to Service A, I need to refetch data from Service B to update the UI without reloading the page. Here’s my setup:

// serviceA.ts (Microservice A)
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const serviceA = createApi({
  reducerPath: 'serviceA',
  baseQuery: fetchBaseQuery({ baseUrl: '/api/serviceA' }),
  endpoints: (builder) => ({
    postData: builder.mutation<void, { message: string }>({
      query: (body) => ({
        url: '/data',
        method: 'POST',
        body,
      }),
    }),
  }),
});

export const { usePostDataMutation } = serviceA;
// serviceB.ts (Microservice B)
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const serviceB = createApi({
  reducerPath: 'serviceB',
  baseQuery: fetchBaseQuery({ baseUrl: '/api/serviceB' }),
  tagTypes: ['Data'],
  endpoints: (builder) => ({
    getData: builder.query<string[], void>({
      query: () => '/data',
      providesTags: ['Data'],
    }),
  }),
});

export const { useGetDataQuery } = serviceB;

After calling postData in Service A, I want to automatically refetch data from Service B to update the UI. I’ve tried using refetch() manually, but I’m looking for a way to handle this automatically.

2

Answers


  1. If I am understanding correctly that these are just two API slices residing within the same Redux store, then you should utilize tag invalidation to trigger any queries to re-run/re-fetch their endpoints.

    For details see:

    Update the serviceA postData mutation endpoint to dispatch the invalidateTags action upon success.

    import { serviceB } from './serviceB';
    
    export const serviceA = createApi({
      reducerPath: 'serviceA',
      baseQuery: fetchBaseQuery({ baseUrl: '/api/serviceA' }),
      endpoints: (builder) => ({
        postData: builder.mutation<void, { message: string }>({
          query: (body) => ({
            url: '/data',
            method: 'POST',
            body,
          }),
          onQueryStarted: async (arg, { dispatch, queryFulfilled }) => {
            try {
              // Wait for mutation to succeed
              await queryFulfilled;
              // Dispatch action to invalidate the 'Data' tag provided
              // by the serviceB getData endpoint
              dispatch(serviceB.util.invalidateTags(['Data']));
            } catch(err) {
              // handle error or ignore
            }
          },
        }),
      }),
    });
    
    Login or Signup to reply.
  2. No matter if they are technically two different microservices – once they handle the same data, they should probably be part of the same createApi-created RTKQ api.

    Generally, there are very few reasons why you should ever have more than one api in your app.

    If these were the same api, you could use automated refetching via tag invalidation, so I recommend you refactor in that direction.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search