Search code examples
reactjstypescriptredux-toolkitrtk-queryzod

How to validate API response in RTK Query using Zod schema?


I want to validate the API response that I'm getting from a REST API using a Zod schema. For example, I have this user schema and this API

import { z } from 'zod';
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';


const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number(),
});

type User = z.infer<typeof userSchema>;


export const userAPI = createApi({
  reducerPath: 'userAPI',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://some-api/' }),
  endpoints: (builder) => ({
    getPokemonByName: builder.query<user, string>({
      query: (id) => `user/${id}`,
    }),
  }),
})

I want to validate the API response against the userSchema using Zod. However, I'm unsure whether to use the parse or safeParse function provided by Zod.

Could you please clarify where in my code should I perform the response validation, and whether I should use parse or safeParse for this scenario?


Solution

  • You can just use transformResponse provided by redux toolkit query to validate the response using the userSchema. If the response doesn't match the schema, an error will be triggered.

    import { z } from 'zod';
    import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
    
    const userSchema = z.object({
      id: z.string(),
      name: z.string(),
      age: z.number(),
    });
    
    type User = z.infer<typeof userSchema>;
    
    export const userAPI = createApi({
      reducerPath: 'userAPI',
      baseQuery: fetchBaseQuery({ baseUrl: 'https://some-api/' }),
      endpoints: (builder) => ({
        getPokemonByName: builder.query<User, string>({
          query: (id) => `user/${id}`,
          transformResponse: (response) => {
            userSchema.parse(response);
            return response;
          },
        }),
      }),
    });
    

    You can also write a wrapper for baseQuery with zod